|
@@ -1,10 +1,21 @@
|
|
|
+use base64::{Engine as _, engine::general_purpose};
|
|
|
+use std::error::Error;
|
|
|
|
|
|
-pub fn uswitch(text: &String) -> String {
|
|
|
- let mut result: String = String::with_capacity(text.len());
|
|
|
- for b in text.bytes() {
|
|
|
- result.push(char::from_u32(b as u32 ^ 'U' as u32).unwrap_or('?'));
|
|
|
+pub fn encode(text: &String) -> String {
|
|
|
+ let mut temp = Vec::with_capacity(text.len());
|
|
|
+ for ch in text.bytes() {
|
|
|
+ temp.push( ch ^ 'U' as u8 );
|
|
|
}
|
|
|
- result
|
|
|
+ general_purpose::STANDARD.encode(temp)
|
|
|
+}
|
|
|
+
|
|
|
+pub fn decode(text: &String) -> Result<String, Box<dyn Error>> {
|
|
|
+ let chars = general_purpose::STANDARD.decode(text)?;
|
|
|
+ let mut temp = Vec::with_capacity(chars.len());
|
|
|
+ for ch in chars {
|
|
|
+ temp.push( ch ^ 'U' as u8 );
|
|
|
+ }
|
|
|
+ Ok(String::from_utf8(temp)?)
|
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
@@ -12,8 +23,36 @@ mod tests {
|
|
|
use super::*;
|
|
|
|
|
|
#[test]
|
|
|
- fn uswitch_test() {
|
|
|
+ fn encode_test() {
|
|
|
let t1: String = String::from("hello world");
|
|
|
- assert_eq!(uswitch(&t1), String::from("=099:u\":'91"));
|
|
|
+ let t2 = encode(&t1);
|
|
|
+ assert_eq!(t2, "PTA5OTp1IjonOTE=");
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn encode_utf8_test() {
|
|
|
+ let t1: String = String::from("🍺");
|
|
|
+ let t2 = encode(&t1);
|
|
|
+ assert_eq!(t2, "pcrY7w==");
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn decode_test() {
|
|
|
+ let t1: String = String::from("ICYiPCE2PW9vMTA2OjEw");
|
|
|
+ let t2 = decode(&t1);
|
|
|
+ match t2 {
|
|
|
+ Ok(s) => assert_eq!(s, "uswitch::decode"),
|
|
|
+ Err(err) => panic!("{}", err),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn decode_utf8_test() {
|
|
|
+ let t1: String = String::from("t9f5");
|
|
|
+ let t2 = decode(&t1);
|
|
|
+ match t2 {
|
|
|
+ Ok(s) => assert_eq!(s, "€"),
|
|
|
+ Err(err) => panic!("{}", err),
|
|
|
+ }
|
|
|
}
|
|
|
}
|