nutek_encode_lib/
lib.rs

1/// This module provides various encoding and decoding functions.
2pub 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    /// Encodes a string into URL-safe Base64 format.
12    ///
13    /// # Examples
14    ///
15    /// ```
16    /// use nutek_encode_lib::encoder;
17    /// let encoded = encoder::encode_urlsafe_base64("hello").unwrap();
18    /// assert_eq!(encoded, "aGVsbG8=");
19    /// ```
20    pub fn encode_urlsafe_base64(data: &str) -> Result<String, Box<dyn Error>> {
21        Ok(URL_SAFE.encode(data.as_bytes()))
22    }
23
24    /// Decodes a URL-safe Base64 encoded string.
25    ///
26    /// # Examples
27    ///
28    /// ```
29    /// use nutek_encode_lib::encoder;
30    /// let decoded = encoder::decode_urlsafe_base64("aGVsbG8=").unwrap();
31    /// assert_eq!(decoded, "hello");
32    /// ```
33    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    /// Encodes a string into standard Base64 format.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// use nutek_encode_lib::encoder;
45    /// let encoded = encoder::encode_base64("hello").unwrap();
46    /// assert_eq!(encoded, "aGVsbG8=");
47    /// ```
48    pub fn encode_base64(data: &str) -> Result<String, Box<dyn Error>> {
49        Ok(BASE64_STANDARD.encode(data.as_bytes()))
50    }
51
52    /// Decodes a standard Base64 encoded string.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// use nutek_encode_lib::encoder;
58    /// let decoded = encoder::decode_base64("aGVsbG8=").unwrap();
59    /// assert_eq!(decoded, "hello");
60    /// ```
61    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    /// Encodes a string into URL percent-encoded format.
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// use nutek_encode_lib::encoder;
73    /// let encoded = encoder::encode_url("hello world!").unwrap();
74    /// assert_eq!(encoded, "hello%20world%21");
75    /// ```
76    pub fn encode_url(data: &str) -> Result<String, Box<dyn Error>> {
77        Ok(utf8_percent_encode(data, NON_ALPHANUMERIC).to_string())
78    }
79
80    /// Decodes a URL percent-encoded string.
81    ///
82    /// # Examples
83    ///
84    /// ```
85    /// use nutek_encode_lib::encoder;
86    /// let decoded = encoder::decode_url("hello%20world%21").unwrap();
87    /// assert_eq!(decoded, "hello world!");
88    /// ```
89    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    /// Encodes a string into binary format.
95    ///
96    /// # Examples
97    ///
98    /// ```
99    /// use nutek_encode_lib::encoder;
100    /// let encoded = encoder::encode_binary("hello").unwrap();
101    /// assert_eq!(encoded, "0110100001100101011011000110110001101111");
102    /// ```
103    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    /// Decodes a binary encoded string.
108    ///
109    /// # Examples
110    ///
111    /// ```
112    /// use nutek_encode_lib::encoder;
113    /// let decoded = encoder::decode_binary("0110100001100101011011000110110001101111").unwrap();
114    /// assert_eq!(decoded, "hello");
115    /// ```
116    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    /// Encodes a string into hexadecimal format.
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// use nutek_encode_lib::encoder;
139    /// let encoded = encoder::encode_hex("hello").unwrap();
140    /// assert_eq!(encoded, "68656c6c6f");
141    /// ```
142    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    /// Decodes a hexadecimal encoded string.
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// use nutek_encode_lib::encoder;
152    /// let decoded = encoder::decode_hex("68656c6c6f").unwrap();
153    /// assert_eq!(decoded, "hello");
154    /// ```
155    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    /// Encodes a string using ROT13.
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// use nutek_encode_lib::encoder;
178    /// let encoded = encoder::encode_rot13("hello").unwrap();
179    /// assert_eq!(encoded, "uryyb");
180    /// ```
181    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    /// Encodes a string into octal format.
198    ///
199    /// # Examples
200    ///
201    /// ```
202    /// use nutek_encode_lib::encoder;
203    /// let encoded = encoder::encode_octal("hello").unwrap();
204    /// assert_eq!(encoded, "150145154154157");
205    /// ```
206    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    /// Decodes an octal encoded string.
211    ///
212    /// # Examples
213    ///
214    /// ```
215    /// use nutek_encode_lib::encoder;
216    /// let decoded = encoder::decode_octal("150145154154157").unwrap();
217    /// assert_eq!(decoded, "hello");
218    /// ```
219    pub fn decode_octal(data: &str) -> Result<String, Box<dyn Error>> {
220        // Check that the overall length is a multiple of 3.
221        if data.len() % 3 != 0 {
222            return Err("Invalid octal data length".into());
223        }
224
225        // Validate that every character is in the octal range '0'..='7'.
226        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        // Process the string in chunks of 3 characters.
235        for chunk in data.as_bytes().chunks(3) {
236            // Convert the chunk (which is a &[u8]) into a &str.
237            let chunk_str = str::from_utf8(chunk)?;
238            // Convert the 3-digit octal string to a u32.
239            let val = u32::from_str_radix(chunk_str, 8)?;
240            // Convert the u32 to a char. If the codepoint is not valid, return an error.
241            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    /// Encodes a string into decimal format.
250    ///
251    /// # Examples
252    ///
253    /// ```
254    /// use nutek_encode_lib::encoder;
255    /// let encoded = encoder::encode_decimal("hello").unwrap();
256    /// assert_eq!(encoded, "104 101 108 108 111");
257    /// ```
258    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    /// Decodes a decimal encoded string.
264    ///
265    /// # Examples
266    ///
267    /// ```
268    /// use nutek_encode_lib::encoder;
269    /// let decoded = encoder::decode_decimal("104 101 108 108 111").unwrap();
270    /// assert_eq!(decoded, "hello");
271    /// ```
272    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    /// Encodes a string into HTML entities.
284    ///
285    /// # Examples
286    ///
287    /// ```
288    /// use nutek_encode_lib::encoder;
289    /// let encoded = encoder::encode_html_entities("hello & world").unwrap();
290    /// assert_eq!(encoded, "hello &amp; world");
291    /// ```
292    pub fn encode_html_entities(data: &str) -> Result<String, Box<dyn Error>> {
293        Ok(encode_minimal(data))
294    }
295
296    /// Decodes a string with HTML entities.
297    ///
298    /// # Examples
299    ///
300    /// ```
301    /// use nutek_encode_lib::encoder;
302    /// let decoded = encoder::decode_html_entities("hello &amp; world").unwrap();
303    /// assert_eq!(decoded, "hello & world");
304    /// ```
305    pub fn decode_html_entities(data: &str) -> Result<String, DecodeErrKind> {
306        decode_html(data).map_err(|e| e.kind)
307    }
308
309    /// Encodes a string into HTML attribute entities.
310    ///
311    /// # Examples
312    ///
313    /// ```
314    /// use nutek_encode_lib::encoder;
315    /// let encoded = encoder::encode_html_entities_attribute("hello & world").unwrap();
316    /// assert_eq!(encoded, "hello&#x20;&amp;&#x20;world");
317    /// ```
318    pub fn encode_html_entities_attribute(data: &str) -> Result<String, Box<dyn Error>> {
319        Ok(encode_attribute(data))
320    }
321
322    /// Decodes a string with HTML attribute entities.
323    ///
324    /// # Examples
325    ///
326    /// ```
327    /// use nutek_encode_lib::encoder;
328    /// let decoded = encoder::decode_html_entities_attribute("hello &amp; world").unwrap();
329    /// assert_eq!(decoded, "hello & world");
330    /// ```
331    pub fn decode_html_entities_attribute(data: &str) -> Result<String, DecodeErrKind> {
332        decode_html_entities(data)
333    }
334
335    /// Encodes an integer string to hexadecimal format.
336    ///
337    /// # Examples
338    ///
339    /// ```
340    /// use nutek_encode_lib::encoder;
341    /// let encoded = encoder::encode_integer_to_hex("255").unwrap();
342    /// assert_eq!(encoded, "ff");
343    /// ```
344    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    /// Encodes an integer string to octal format.
350    ///
351    /// # Examples
352    ///
353    /// ```
354    /// use nutek_encode_lib::encoder;
355    /// let encoded = encoder::encode_integer_to_octal("255").unwrap();
356    /// assert_eq!(encoded, "377");
357    /// ```
358    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    /// Encodes an integer string to binary format.
364    ///
365    /// # Examples
366    ///
367    /// ```
368    /// use nutek_encode_lib::encoder;
369    /// let encoded = encoder::encode_integer_to_binary("255").unwrap();
370    /// assert_eq!(encoded, "11111111");
371    /// ```
372    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    /// Encodes a hexadecimal string to integer format.
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// use nutek_encode_lib::encoder;
383    /// let encoded = encoder::encode_hex_to_integer("ff").unwrap();
384    /// assert_eq!(encoded, "255");
385    /// ```
386    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    /// Encodes a hexadecimal string to binary format.
392    ///
393    /// # Examples
394    ///
395    /// ```
396    /// use nutek_encode_lib::encoder;
397    /// let encoded = encoder::encode_hex_to_binary("ff").unwrap();
398    /// assert_eq!(encoded, "11111111");
399    /// ```
400    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    /// Encodes a hexadecimal string to octal format.
406    ///
407    /// # Examples
408    ///
409    /// ```
410    /// use nutek_encode_lib::encoder;
411    /// let encoded = encoder::encode_hex_to_octal("ff").unwrap();
412    /// assert_eq!(encoded, "377");
413    /// ```
414    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    /// Encodes an octal string to integer format.
420    ///
421    /// # Examples
422    ///
423    /// ```
424    /// use nutek_encode_lib::encoder;
425    /// let encoded = encoder::encode_octal_to_integer("377").unwrap();
426    /// assert_eq!(encoded, "255");
427    /// ```
428    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    /// Encodes an octal string to hexadecimal format.
434    ///
435    /// # Examples
436    ///
437    /// ```
438    /// use nutek_encode_lib::encoder;
439    /// let encoded = encoder::encode_octal_to_hex("377").unwrap();
440    /// assert_eq!(encoded, "ff");
441    /// ```
442    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    /// Encodes an octal string to binary format.
448    ///
449    /// # Examples
450    ///
451    /// ```
452    /// use nutek_encode_lib::encoder;
453    /// let encoded = encoder::encode_octal_to_binary("377").unwrap();
454    /// assert_eq!(encoded, "11111111");
455    /// ```
456    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    /// Encodes a binary string to hexadecimal format.
462    ///
463    /// # Examples
464    ///
465    /// ```
466    /// use nutek_encode_lib::encoder;
467    /// let encoded = encoder::encode_binary_to_hex("11111111").unwrap();
468    /// assert_eq!(encoded, "ff");
469    /// ```
470    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    /// Encodes a binary string to octal format.
476    ///
477    /// # Examples
478    ///
479    /// ```
480    /// use nutek_encode_lib::encoder;
481    /// let encoded = encoder::encode_binary_to_octal("11111111").unwrap();
482    /// assert_eq!(encoded, "377");
483    /// ```
484    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    /// Encodes a binary string to integer format.
490    ///
491    /// # Examples
492    ///
493    /// ```
494    /// use nutek_encode_lib::encoder;
495    /// let encoded = encoder::encode_binary_to_integer("11111111").unwrap();
496    /// assert_eq!(encoded, "255");
497    /// ```
498    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    /// Encodes a string using SHA-1.
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// use nutek_encode_lib::encoder;
509    /// let encoded = encoder::encode_sha1("hello").unwrap();
510    /// assert_eq!(encoded, "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d");
511    /// ```
512    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    /// Encodes a string using SHA-256.
520    ///
521    /// # Examples
522    ///
523    /// ```
524    /// use nutek_encode_lib::encoder;
525    /// let encoded = encoder::encode_sha256("hello").unwrap();
526    /// assert_eq!(encoded, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824");
527    /// ```
528    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    /// Encodes a string using SHA-512.
536    ///
537    /// # Examples
538    ///
539    /// ```
540    /// use nutek_encode_lib::encoder;
541    /// let encoded = encoder::encode_sha512("hello").unwrap();
542    /// assert!(encoded.starts_with("9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"));
543    /// ```
544    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    /// Encodes a string using SHA-384.
552    ///
553    /// # Examples
554    ///
555    /// ```
556    /// use nutek_encode_lib::encoder;
557    /// let encoded = encoder::encode_sha384("hello").unwrap();
558    /// assert!(encoded.starts_with("59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f"));
559    /// ```
560    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    /// Encodes a string using SHA-224.
568    ///
569    /// # Examples
570    ///
571    /// ```
572    /// use nutek_encode_lib::encoder;
573    /// let encoded = encoder::encode_sha224("hello").unwrap();
574    /// assert!(encoded.starts_with("ea09ae9cc6768c50fcee903ed054556e5bfc8347907f12598aa24193"));
575    /// ```
576    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    /// Encodes a string using SHA-512/256.
584    ///
585    /// # Examples
586    ///
587    /// ```
588    /// use nutek_encode_lib::encoder;
589    /// let encoded = encoder::encode_sha512_256("hello").unwrap();
590    /// assert!(encoded.starts_with("e30d87cfa2a75db545eac4d61baf970366a8357c7f72fa95b52d0accb698f13a"));
591    /// ```
592    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    /// Encodes a string using SHA-512/224.
600    ///
601    /// # Examples
602    ///
603    /// ```
604    /// use nutek_encode_lib::encoder;
605    /// let encoded = encoder::encode_sha512_224("hello").unwrap();
606    /// assert!(encoded.starts_with("fe8509ed1fb7dcefc27e6ac1a80eddbec4cb3d2c6fe565244374061c"));
607    /// ```
608    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    /// Encodes a string using MD5.
616    ///
617    /// # Examples
618    ///
619    /// ```
620    /// use nutek_encode_lib::encoder;
621    /// let encoded = encoder::encode_md5("hello").unwrap();
622    /// assert_eq!(encoded, "5d41402abc4b2a76b9719d911017c592");
623    /// ```
624    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        // Malformed input
649        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        // Malformed input
668        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        // Malformed input
701        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        // Malformed input
737        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        // Malformed input
756        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        // Malformed input
775        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        // Malformed input
780        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        // Malformed input
785        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        // Malformed input
790        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        // Malformed input
795        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, "&lt;br&gt;&lt;p&gt;hello world&lt;/p&gt;");
805    }
806
807    #[test]
808    fn it_decodes_html_entities() {
809        let data = "&lt;br&gt;&lt;p&gt;hello world&lt;/p&gt;";
810        let decoded = decode_html_entities(data).unwrap();
811        assert_eq!(decoded, "<br><p>hello world</p>");
812
813        // Malformed input
814        let malformed_data = "&thisentitydoesnotexist;";
815        let result = decode_html_entities(malformed_data);
816        assert!(result.is_err());
817
818        // Malformed input
819        let malformed_data = "&#xfoo;";
820        let result = decode_html_entities(malformed_data);
821        assert!(result.is_err());
822
823        // Malformed input
824        let malformed_data = "&#xffffff;";
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            "&lt;br&gt;&lt;p&gt;hello&#x20;world&lt;&#x2F;p&gt;"
836        );
837    }
838
839    #[test]
840    fn it_decodes_html_entities_attribute() {
841        let data = "&lt;br&gt;&lt;p&gt;hello&#x20;world&lt;&#x2F;p&gt;";
842        let decoded = decode_html_entities_attribute(data).unwrap();
843        assert_eq!(decoded, "<br><p>hello world</p>");
844
845        // Malformed input
846        let malformed_data = "&thisentitydoesnotexist;";
847        let result = decode_html_entities_attribute(malformed_data);
848        assert!(result.is_err());
849
850        // Malformed input
851        let malformed_data = "&#xfoo;";
852        let result = decode_html_entities_attribute(malformed_data);
853        assert!(result.is_err());
854
855        // Malformed input
856        let malformed_data = "&#xffffff;";
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        // Malformed input
868        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        // Malformed input
880        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        // Malformed input
892        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        // Malformed input
904        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        // Malformed input
916        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        // Malformed input
928        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        // Malformed input
940        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        // Malformed input
952        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        // Malformed input
964        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        // Malformed input
976        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        // Malformed input
988        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        // Malformed input
1000        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}