1pub mod encoder {
3 use base64::{Engine as _, engine::general_purpose::URL_SAFE, prelude::BASE64_STANDARD};
4 use hex;
5 use htmlescape::{DecodeErrKind, decode_html, encode_attribute, encode_minimal};
6 use percent_encoding::{NON_ALPHANUMERIC, utf8_percent_encode};
7 use sha1::{Digest as Digest1, Sha1};
8 use sha2::{Sha224, Sha256, Sha384, Sha512, Sha512_224, Sha512_256};
9 use std::{error::Error, str};
10
11 pub fn encode_urlsafe_base64(data: &str) -> Result<String, Box<dyn Error>> {
21 Ok(URL_SAFE.encode(data.as_bytes()))
22 }
23
24 pub fn decode_urlsafe_base64(data: &str) -> Result<String, Box<dyn Error>> {
34 let decoded_bytes = URL_SAFE.decode(data.as_bytes())?;
35 let decoded_str = String::from_utf8(decoded_bytes)?;
36 Ok(decoded_str)
37 }
38
39 pub fn encode_base64(data: &str) -> Result<String, Box<dyn Error>> {
49 Ok(BASE64_STANDARD.encode(data.as_bytes()))
50 }
51
52 pub fn decode_base64(data: &str) -> Result<String, Box<dyn Error>> {
62 let decoding_result = BASE64_STANDARD.decode(data)?;
63 let decoded_str = std::str::from_utf8(&decoding_result)?;
64 Ok(decoded_str.to_string())
65 }
66
67 pub fn encode_url(data: &str) -> Result<String, Box<dyn Error>> {
77 Ok(utf8_percent_encode(data, NON_ALPHANUMERIC).to_string())
78 }
79
80 pub fn decode_url(data: &str) -> Result<String, Box<dyn Error>> {
90 let decoded_str = percent_encoding::percent_decode_str(data).decode_utf8()?;
91 Ok(decoded_str.to_string())
92 }
93
94 pub fn encode_binary(data: &str) -> Result<String, Box<dyn Error>> {
104 Ok(data.chars().map(|c| format!("{:08b}", c as u8)).collect())
105 }
106
107 pub fn decode_binary(data: &str) -> Result<String, Box<dyn Error>> {
117 if data.len() % 8 != 0 {
118 return Err("Invalid binary data length".into());
119 }
120 let decoded_str: Result<String, Box<dyn Error>> = data
121 .chars()
122 .collect::<Vec<_>>()
123 .chunks(8)
124 .map(|chunk| {
125 let s: String = chunk.iter().collect();
126 let char_result = char::from_u32(u32::from_str_radix(&s, 2)?);
127 char_result.ok_or_else(|| "Invalid binary data".into())
128 })
129 .collect();
130 decoded_str
131 }
132
133 pub fn encode_hex(data: &str) -> Result<String, Box<dyn Error>> {
143 Ok(data.chars().map(|c| format!("{:02x}", c as u8)).collect())
144 }
145
146 pub fn decode_hex(data: &str) -> Result<String, Box<dyn Error>> {
156 if data.len() % 2 != 0 {
157 return Err("Invalid hex data length".into());
158 }
159 let decoded_str: Result<String, Box<dyn Error>> = data
160 .chars()
161 .collect::<Vec<_>>()
162 .chunks(2)
163 .map(|chunk| {
164 let s: String = chunk.iter().collect();
165 let char_result = char::from_u32(u32::from_str_radix(&s, 16)?);
166 char_result.ok_or_else(|| "Invalid hex data".into())
167 })
168 .collect();
169 decoded_str
170 }
171
172 pub fn encode_rot13(data: &str) -> Result<String, Box<dyn Error>> {
182 Ok(data
183 .chars()
184 .map(|c| {
185 if c.is_ascii_alphabetic() {
186 let first = if c.is_ascii_lowercase() { b'a' } else { b'A' };
187 let offset = (c as u8).wrapping_sub(first);
188 let rotated = (offset + 13) % 26;
189 (first + rotated) as char
190 } else {
191 c
192 }
193 })
194 .collect())
195 }
196
197 pub fn encode_octal(data: &str) -> Result<String, Box<dyn Error>> {
207 Ok(data.chars().map(|c| format!("{:03o}", c as u8)).collect())
208 }
209
210 pub fn decode_octal(data: &str) -> Result<String, Box<dyn Error>> {
220 if data.len() % 3 != 0 {
222 return Err("Invalid octal data length".into());
223 }
224
225 for (i, ch) in data.chars().enumerate() {
227 if ch < '0' || ch > '7' {
228 return Err(format!("Invalid octal digit '{}' at position {}", ch, i).into());
229 }
230 }
231
232 let mut result = String::new();
233
234 for chunk in data.as_bytes().chunks(3) {
236 let chunk_str = str::from_utf8(chunk)?;
238 let val = u32::from_str_radix(chunk_str, 8)?;
240 match char::from_u32(val) {
242 Some(ch) => result.push(ch),
243 None => return Err(format!("Invalid octal codepoint: {}", chunk_str).into()),
244 }
245 }
246 Ok(result)
247 }
248
249 pub fn encode_decimal(data: &str) -> Result<String, Box<dyn Error>> {
259 let decimal_encoded: String = data.chars().map(|c| format!("{:03} ", c as u8)).collect();
260 Ok(decimal_encoded.trim().to_string())
261 }
262
263 pub fn decode_decimal(data: &str) -> Result<String, Box<dyn Error>> {
273 let decoded_str: Result<String, Box<dyn Error>> = data
274 .split_whitespace()
275 .map(|s| {
276 let char_result = char::from_u32(s.parse()?);
277 char_result.ok_or_else(|| "Invalid decimal data".into())
278 })
279 .collect();
280 decoded_str
281 }
282
283 pub fn encode_html_entities(data: &str) -> Result<String, Box<dyn Error>> {
293 Ok(encode_minimal(data))
294 }
295
296 pub fn decode_html_entities(data: &str) -> Result<String, DecodeErrKind> {
306 decode_html(data).map_err(|e| e.kind)
307 }
308
309 pub fn encode_html_entities_attribute(data: &str) -> Result<String, Box<dyn Error>> {
319 Ok(encode_attribute(data))
320 }
321
322 pub fn decode_html_entities_attribute(data: &str) -> Result<String, DecodeErrKind> {
332 decode_html_entities(data)
333 }
334
335 pub fn encode_integer_to_hex(data: &str) -> Result<String, Box<dyn Error>> {
345 let parsed_int = data.parse::<u32>()?;
346 Ok(format!("{:02x}", parsed_int))
347 }
348
349 pub fn encode_integer_to_octal(data: &str) -> Result<String, Box<dyn Error>> {
359 let parsed_int = data.parse::<u32>()?;
360 Ok(format!("{:03o}", parsed_int))
361 }
362
363 pub fn encode_integer_to_binary(data: &str) -> Result<String, Box<dyn Error>> {
373 let parsed_int = data.parse::<u32>()?;
374 Ok(format!("{:08b}", parsed_int))
375 }
376
377 pub fn encode_hex_to_integer(data: &str) -> Result<String, Box<dyn Error>> {
387 let parsed_int = u32::from_str_radix(data, 16)?;
388 Ok(parsed_int.to_string())
389 }
390
391 pub fn encode_hex_to_binary(data: &str) -> Result<String, Box<dyn Error>> {
401 let parsed_int = u32::from_str_radix(data, 16)?;
402 Ok(format!("{:08b}", parsed_int))
403 }
404
405 pub fn encode_hex_to_octal(data: &str) -> Result<String, Box<dyn Error>> {
415 let parsed_int = u32::from_str_radix(data, 16)?;
416 Ok(format!("{:03o}", parsed_int))
417 }
418
419 pub fn encode_octal_to_integer(data: &str) -> Result<String, Box<dyn Error>> {
429 let parsed_int = u32::from_str_radix(data, 8)?;
430 Ok(parsed_int.to_string())
431 }
432
433 pub fn encode_octal_to_hex(data: &str) -> Result<String, Box<dyn Error>> {
443 let parsed_int = u32::from_str_radix(data, 8)?;
444 Ok(format!("{:02x}", parsed_int))
445 }
446
447 pub fn encode_octal_to_binary(data: &str) -> Result<String, Box<dyn Error>> {
457 let parsed_int = u32::from_str_radix(data, 8)?;
458 Ok(format!("{:08b}", parsed_int))
459 }
460
461 pub fn encode_binary_to_hex(data: &str) -> Result<String, Box<dyn Error>> {
471 let parsed_int = u32::from_str_radix(data, 2)?;
472 Ok(format!("{:02x}", parsed_int))
473 }
474
475 pub fn encode_binary_to_octal(data: &str) -> Result<String, Box<dyn Error>> {
485 let parsed_int = u32::from_str_radix(data, 2)?;
486 Ok(format!("{:03o}", parsed_int))
487 }
488
489 pub fn encode_binary_to_integer(data: &str) -> Result<String, Box<dyn Error>> {
499 let parsed_int = u32::from_str_radix(data, 2)?;
500 Ok(parsed_int.to_string())
501 }
502
503 pub fn encode_sha1(data: &str) -> Result<String, Box<dyn Error>> {
513 let mut hasher = Sha1::new();
514 hasher.update(data);
515 let result = hasher.finalize();
516 Ok(hex::encode(result))
517 }
518
519 pub fn encode_sha256(data: &str) -> Result<String, Box<dyn Error>> {
529 let mut hasher = Sha256::new();
530 hasher.update(data);
531 let result = hasher.finalize();
532 Ok(hex::encode(result))
533 }
534
535 pub fn encode_sha512(data: &str) -> Result<String, Box<dyn Error>> {
545 let mut hasher = Sha512::new();
546 hasher.update(data);
547 let result = hasher.finalize();
548 Ok(hex::encode(result))
549 }
550
551 pub fn encode_sha384(data: &str) -> Result<String, Box<dyn Error>> {
561 let mut hasher = Sha384::new();
562 hasher.update(data);
563 let result = hasher.finalize();
564 Ok(hex::encode(result))
565 }
566
567 pub fn encode_sha224(data: &str) -> Result<String, Box<dyn Error>> {
577 let mut hasher = Sha224::new();
578 hasher.update(data);
579 let result = hasher.finalize();
580 Ok(hex::encode(result))
581 }
582
583 pub fn encode_sha512_256(data: &str) -> Result<String, Box<dyn Error>> {
593 let mut hasher = Sha512_256::new();
594 hasher.update(data);
595 let result = hasher.finalize();
596 Ok(hex::encode(result))
597 }
598
599 pub fn encode_sha512_224(data: &str) -> Result<String, Box<dyn Error>> {
609 let mut hasher = Sha512_224::new();
610 hasher.update(data);
611 let result = hasher.finalize();
612 Ok(hex::encode(result))
613 }
614
615 pub fn encode_md5(data: &str) -> Result<String, Box<dyn Error>> {
625 let result = md5::compute(data);
626 Ok(format!("{:x}", result))
627 }
628}
629
630#[cfg(test)]
631mod tests_encoder {
632 use super::*;
633 use encoder::*;
634
635 #[test]
636 fn it_encodes_base64() {
637 let data = "hello world";
638 let encoded = encode_base64(data).unwrap();
639 assert_eq!(encoded, "aGVsbG8gd29ybGQ=");
640 }
641
642 #[test]
643 fn it_decodes_base64() {
644 let data = "aGVsbG8gd29ybGQ=";
645 let decoded = decode_base64(data).unwrap();
646 assert_eq!(decoded, "hello world");
647
648 let malformed_data = "aGVsbG8gd29ybGQ";
650 let result = decode_base64(malformed_data);
651 assert!(result.is_err());
652 }
653
654 #[test]
655 fn it_encodes_urlsafe_base64() {
656 let data = "hello world";
657 let encoded = encode_urlsafe_base64(data).unwrap();
658 assert_eq!(encoded, "aGVsbG8gd29ybGQ=");
659 }
660
661 #[test]
662 fn it_decodes_urlsafe_base64() {
663 let data = "aGVsbG8gd29ybGQ=";
664 let decoded = decode_urlsafe_base64(data).unwrap();
665 assert_eq!(decoded, "hello world");
666
667 let malformed_data = "aGVsbG8gd29ybGQ";
669 let result = decode_urlsafe_base64(malformed_data);
670 assert!(result.is_err());
671 }
672
673 #[test]
674 fn it_encodes_url() {
675 let data = "hello world";
676 let encoded = encode_url(data).unwrap();
677 assert_eq!(encoded, "hello%20world");
678 }
679
680 #[test]
681 fn it_decodes_url() {
682 let data = "hello%20world";
683 let decoded = decode_url(data).unwrap();
684 assert_eq!(decoded, "hello world");
685 }
686
687 #[test]
688 fn it_encodes_hex() {
689 let data = "hello world";
690 let encoded = encode_hex(data).unwrap();
691 assert_eq!(encoded, "68656c6c6f20776f726c64");
692 }
693
694 #[test]
695 fn it_decodes_hex() {
696 let data = "68656c6c6f20776f726c64";
697 let decoded = decode_hex(data).unwrap();
698 assert_eq!(decoded, "hello world");
699
700 let malformed_data = "68656c6c6f20776f726c6";
702 let result = decode_hex(malformed_data);
703 assert!(result.is_err());
704 }
705
706 #[test]
707 fn it_encodes_rot13() {
708 let data = "hello world";
709 let encoded = encode_rot13(data).unwrap();
710 assert_eq!(encoded, "uryyb jbeyq");
711 }
712
713 #[test]
714 fn it_decodes_rot13() {
715 let data = "uryyb jbeyq";
716 let decoded = encode_rot13(data).unwrap();
717 assert_eq!(decoded, "hello world");
718 }
719
720 #[test]
721 fn it_encodes_binary() {
722 let data = "hello world";
723 let encoded = encode_binary(data).unwrap();
724 assert_eq!(
725 encoded,
726 "0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100"
727 );
728 }
729
730 #[test]
731 fn it_decodes_binary() {
732 let data = "0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100";
733 let decoded = decode_binary(data).unwrap();
734 assert_eq!(decoded, "hello world");
735
736 let malformed_data = "011010000110010101101100011011000110111100100000011101110110111101110010011011000110010";
738 let result = decode_binary(malformed_data);
739 assert!(result.is_err());
740 }
741
742 #[test]
743 fn it_encodes_octal() {
744 let data = "hello world";
745 let encoded = encode_octal(data).unwrap();
746 assert_eq!(encoded, "150145154154157040167157162154144");
747 }
748
749 #[test]
750 fn it_decodes_octal() {
751 let data = "150145154154157040167157162154144";
752 let decoded = decode_octal(data).unwrap();
753 assert_eq!(decoded, "hello world");
754
755 let malformed_data = "15014515415415704016715716215414";
757 let result = decode_octal(malformed_data);
758 assert!(result.is_err());
759 }
760
761 #[test]
762 fn it_encodes_decimal() {
763 let data = "hello world";
764 let encoded = encode_decimal(data).unwrap();
765 assert_eq!(encoded, "104 101 108 108 111 032 119 111 114 108 100");
766 }
767
768 #[test]
769 fn it_decodes_decimal() {
770 let data = "104 101 108 108 111 32 119 111 114 108 100";
771 let decoded = decode_decimal(data).unwrap();
772 assert_eq!(decoded, "hello world");
773
774 let malformed_data = "104 101 108 108 111 032 119 111 114 108 abc";
776 let result = decode_decimal(malformed_data);
777 assert!(result.is_err());
778
779 let malformed_data = "104 101 108 108 111 032 119 111 114 108 9999999999";
781 let result = decode_decimal(malformed_data);
782 assert!(result.is_err());
783
784 let malformed_data = "104 101 108 108 111 032 119 111 114 108 -1";
786 let result = decode_decimal(malformed_data);
787 assert!(result.is_err());
788
789 let malformed_data = "104 101 108 108 111 032 119 111 114 108 65.5";
791 let result = decode_decimal(malformed_data);
792 assert!(result.is_err());
793
794 let malformed_data = "104 101 108 108 111 032 119 111 114 108 256 abc";
796 let result = decode_decimal(malformed_data);
797 assert!(result.is_err());
798 }
799
800 #[test]
801 fn it_encodes_html_entities_minimal() {
802 let data = "<br><p>hello world</p>";
803 let encoded = encode_html_entities(data).unwrap();
804 assert_eq!(encoded, "<br><p>hello world</p>");
805 }
806
807 #[test]
808 fn it_decodes_html_entities() {
809 let data = "<br><p>hello world</p>";
810 let decoded = decode_html_entities(data).unwrap();
811 assert_eq!(decoded, "<br><p>hello world</p>");
812
813 let malformed_data = "&thisentitydoesnotexist;";
815 let result = decode_html_entities(malformed_data);
816 assert!(result.is_err());
817
818 let malformed_data = "oo;";
820 let result = decode_html_entities(malformed_data);
821 assert!(result.is_err());
822
823 let malformed_data = "�";
825 let result = decode_html_entities(malformed_data);
826 assert!(result.is_err());
827 }
828
829 #[test]
830 fn it_encodes_html_entities_attribute() {
831 let data = "<br><p>hello world</p>";
832 let encoded = encode_html_entities_attribute(data).unwrap();
833 assert_eq!(
834 encoded,
835 "<br><p>hello world</p>"
836 );
837 }
838
839 #[test]
840 fn it_decodes_html_entities_attribute() {
841 let data = "<br><p>hello world</p>";
842 let decoded = decode_html_entities_attribute(data).unwrap();
843 assert_eq!(decoded, "<br><p>hello world</p>");
844
845 let malformed_data = "&thisentitydoesnotexist;";
847 let result = decode_html_entities_attribute(malformed_data);
848 assert!(result.is_err());
849
850 let malformed_data = "oo;";
852 let result = decode_html_entities_attribute(malformed_data);
853 assert!(result.is_err());
854
855 let malformed_data = "�";
857 let result = decode_html_entities_attribute(malformed_data);
858 assert!(result.is_err());
859 }
860
861 #[test]
862 fn it_encodes_integer_to_hex() {
863 let data = "10";
864 let encoded = encode_integer_to_hex(data).unwrap();
865 assert_eq!(encoded, "0a");
866
867 let malformed_data = "ten";
869 let result = encode_integer_to_hex(malformed_data);
870 assert!(result.is_err());
871 }
872
873 #[test]
874 fn it_encodes_integer_to_octal() {
875 let data = "10";
876 let encoded = encode_integer_to_octal(data).unwrap();
877 assert_eq!(encoded, "012");
878
879 let malformed_data = "ten";
881 let result = encode_integer_to_octal(malformed_data);
882 assert!(result.is_err());
883 }
884
885 #[test]
886 fn it_encodes_integer_to_binary() {
887 let data = "10";
888 let encoded = encode_integer_to_binary(data).unwrap();
889 assert_eq!(encoded, "00001010");
890
891 let malformed_data = "ten";
893 let result = encode_integer_to_binary(malformed_data);
894 assert!(result.is_err());
895 }
896
897 #[test]
898 fn it_encodes_hex_to_integer() {
899 let data = "0a";
900 let decoded = encode_hex_to_integer(data).unwrap();
901 assert_eq!(decoded, "10");
902
903 let malformed_data = "0g";
905 let result = encode_hex_to_integer(malformed_data);
906 assert!(result.is_err());
907 }
908
909 #[test]
910 fn it_encodes_hex_to_binary() {
911 let data = "0a";
912 let encoded = encode_hex_to_binary(data).unwrap();
913 assert_eq!(encoded, "00001010");
914
915 let malformed_data = "0g";
917 let result = encode_hex_to_binary(malformed_data);
918 assert!(result.is_err());
919 }
920
921 #[test]
922 fn it_encodes_hex_to_octal() {
923 let data = "0a";
924 let encoded = encode_hex_to_octal(data).unwrap();
925 assert_eq!(encoded, "012");
926
927 let malformed_data = "0g";
929 let result = encode_hex_to_octal(malformed_data);
930 assert!(result.is_err());
931 }
932
933 #[test]
934 fn it_encodes_octal_to_integer() {
935 let data = "012";
936 let decoded = encode_octal_to_integer(data).unwrap();
937 assert_eq!(decoded, "10");
938
939 let malformed_data = "018";
941 let result = encode_octal_to_integer(malformed_data);
942 assert!(result.is_err());
943 }
944
945 #[test]
946 fn it_encodes_octal_to_hex() {
947 let data = "012";
948 let encoded = encode_octal_to_hex(data).unwrap();
949 assert_eq!(encoded, "0a");
950
951 let malformed_data = "018";
953 let result = encode_octal_to_hex(malformed_data);
954 assert!(result.is_err());
955 }
956
957 #[test]
958 fn it_encodes_octal_to_binary() {
959 let data = "012";
960 let encoded = encode_octal_to_binary(data).unwrap();
961 assert_eq!(encoded, "00001010");
962
963 let malformed_data = "018";
965 let result = encode_octal_to_binary(malformed_data);
966 assert!(result.is_err());
967 }
968
969 #[test]
970 fn it_encodes_binary_to_hex() {
971 let data = "00001010";
972 let encoded = encode_binary_to_hex(data).unwrap();
973 assert_eq!(encoded, "0a");
974
975 let malformed_data = "00001210";
977 let result = encode_binary_to_hex(malformed_data);
978 assert!(result.is_err());
979 }
980
981 #[test]
982 fn it_encodes_binary_to_octal() {
983 let data = "00001010";
984 let encoded = encode_binary_to_octal(data).unwrap();
985 assert_eq!(encoded, "012");
986
987 let malformed_data = "00001210";
989 let result = encode_binary_to_octal(malformed_data);
990 assert!(result.is_err());
991 }
992
993 #[test]
994 fn it_encodes_binary_to_integer() {
995 let data = "00001010";
996 let decoded = encode_binary_to_integer(data).unwrap();
997 assert_eq!(decoded, "10");
998
999 let malformed_data = "00001210";
1001 let result = encode_binary_to_integer(malformed_data);
1002 assert!(result.is_err());
1003 }
1004
1005 #[test]
1006 fn it_encodes_sha1() {
1007 let data = "hello world";
1008 let encoded = encode_sha1(data).unwrap();
1009 assert_eq!(encoded, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
1010 }
1011
1012 #[test]
1013 fn it_encodes_sha256() {
1014 let data = "hello world";
1015 let encoded = encode_sha256(data).unwrap();
1016 assert_eq!(
1017 encoded,
1018 "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
1019 );
1020 }
1021
1022 #[test]
1023 fn it_encodes_sha512() {
1024 let data = "hello world";
1025 let encoded = encode_sha512(data).unwrap();
1026 assert_eq!(
1027 encoded,
1028 "309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f"
1029 );
1030 }
1031
1032 #[test]
1033 fn it_encodes_sha384() {
1034 let data = "hello world";
1035 let encoded = encode_sha384(data).unwrap();
1036 assert_eq!(
1037 encoded,
1038 "fdbd8e75a67f29f701a4e040385e2e23986303ea10239211af907fcbb83578b3e417cb71ce646efd0819dd8c088de1bd"
1039 );
1040 }
1041
1042 #[test]
1043 fn it_encodes_sha224() {
1044 let data = "hello world";
1045 let encoded = encode_sha224(data).unwrap();
1046 assert_eq!(
1047 encoded,
1048 "2f05477fc24bb4faefd86517156dafdecec45b8ad3cf2522a563582b"
1049 );
1050 }
1051
1052 #[test]
1053 fn it_encodes_sha512_256() {
1054 let data = "hello world";
1055 let encoded = encode_sha512_256(data).unwrap();
1056 assert_eq!(
1057 encoded,
1058 "0ac561fac838104e3f2e4ad107b4bee3e938bf15f2b15f009ccccd61a913f017"
1059 );
1060 }
1061
1062 #[test]
1063 fn it_encodes_sha512_224() {
1064 let data = "hello world";
1065 let encoded = encode_sha512_224(data).unwrap();
1066 assert_eq!(
1067 encoded,
1068 "22e0d52336f64a998085078b05a6e37b26f8120f43bf4db4c43a64ee"
1069 );
1070 }
1071
1072 #[test]
1073 fn it_encodes_md5() {
1074 let data = "hello world";
1075 let encoded = encode_md5(data).unwrap();
1076 assert_eq!(encoded, "5eb63bbbe01eeed093cb22bb8f5acdc3");
1077 }
1078}