1use md5::Md5 as Md5Hasher;
9use sha2::{Digest as Sha2Digest, Sha256 as Sha2_256};
10
11#[polydat::polydat_node(category = Digest)]
17fn sha256(input: &[u8]) -> Vec<u8> {
18 let mut hasher = Sha2_256::new();
19 hasher.update(input);
20 hasher.finalize().to_vec()
21}
22
23#[polydat::polydat_node(category = Digest)]
24fn md5(input: &[u8]) -> Vec<u8> {
25 let mut hasher = Md5Hasher::new();
26 hasher.update(input);
27 hasher.finalize().to_vec()
28}
29
30#[polydat::polydat_node(category = Digest)]
31fn to_base64(input: &[u8]) -> String {
32 use base64::Engine;
33 base64::engine::general_purpose::STANDARD.encode(input)
34}
35
36#[polydat::polydat_node(category = Digest)]
37fn from_base64(input: &str) -> Vec<u8> {
38 use base64::Engine;
39 base64::engine::general_purpose::STANDARD
40 .decode(input)
41 .unwrap_or_default()
42}
43
44#[polydat::polydat_node(category = Digest)]
45fn to_base32(input: &[u8]) -> String {
46 data_encoding::BASE32.encode(input)
47}
48
49#[polydat::polydat_node(category = Digest)]
50fn from_base32(input: &str) -> Vec<u8> {
51 data_encoding::BASE32
52 .decode(input.as_bytes())
53 .unwrap_or_default()
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use polydat::ast::{PolydatNode, Value};
60
61 #[test]
62 fn sha256_known() {
63 let node = Sha256::default();
64 let mut out = [Value::None];
65 node.eval(&[Value::Bytes(vec![].into())], &mut out[..]);
67 let bytes = out[0].as_bytes();
68 assert_eq!(bytes.len(), 32);
69 assert_eq!(bytes[0], 0xe3);
71 assert_eq!(bytes[1], 0xb0);
72 }
73
74 #[test]
75 fn sha256_deterministic() {
76 let node = Sha256::default();
77 let mut out1 = [Value::None];
78 let mut out2 = [Value::None];
79 let input = Value::Bytes(b"hello world".to_vec().into());
80 node.eval(std::slice::from_ref(&input), &mut out1);
81 node.eval(&[input], &mut out2);
82 assert_eq!(out1[0].as_bytes(), out2[0].as_bytes());
83 }
84
85 #[test]
86 fn md5_known() {
87 let node = Md5::default();
88 let mut out = [Value::None];
89 node.eval(&[Value::Bytes(vec![].into())], &mut out[..]);
90 let bytes = out[0].as_bytes();
91 assert_eq!(bytes.len(), 16);
92 assert_eq!(bytes[0], 0xd4);
94 }
95
96 #[test]
97 fn base64_roundtrip() {
98 let enc = ToBase64::default();
99 let dec = FromBase64::default();
100 let mut mid = [Value::None];
101 let mut out = [Value::None];
102 let input = vec![0xDE, 0xAD, 0xBE, 0xEF, 0x42];
103 enc.eval(&[Value::Bytes(input.clone().into())], &mut mid[..]);
104 dec.eval(&[mid[0].clone()], &mut out);
105 assert_eq!(out[0].as_bytes(), &input);
106 }
107
108 #[test]
109 fn base32_roundtrip() {
110 let enc = ToBase32::default();
111 let dec = FromBase32::default();
112 let mut mid = [Value::None];
113 let mut out = [Value::None];
114 let input = vec![0xDE, 0xAD, 0xBE, 0xEF, 0x42];
115 enc.eval(&[Value::Bytes(input.clone().into())], &mut mid[..]);
116 dec.eval(&[mid[0].clone()], &mut out);
117 assert_eq!(out[0].as_bytes(), &input);
118 }
119}