rok_utils/data/
hashing.rs1#[cfg(feature = "crypto")]
2pub fn hash_sha256(input: &str) -> String {
3 use sha2::{Digest, Sha256};
4 let mut hasher = Sha256::new();
5 hasher.update(input.as_bytes());
6 format!("{:x}", hasher.finalize())
7}
8
9#[cfg(feature = "crypto")]
10pub fn verify_sha256(input: &str, expected: &str) -> bool {
11 hash_sha256(input) == expected
12}
13
14#[cfg(feature = "crypto")]
15pub fn generate_token(bytes: usize) -> String {
16 use base64::Engine;
17 let random: Vec<u8> = (0..bytes).map(|_| rand::random::<u8>()).collect();
18 base64::engine::general_purpose::URL_SAFE.encode(&random)
19}
20
21#[cfg(feature = "crypto")]
22pub fn secure_compare(a: &str, b: &str) -> bool {
23 use subtle::ConstantTimeEq;
24 if a.len() != b.len() {
25 return false;
26 }
27 a.as_bytes().ct_eq(b.as_bytes()).unwrap_u8() == 1
28}
29
30#[cfg(feature = "crypto")]
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn test_hash_sha256() {
37 let h = hash_sha256("hello");
38 assert_eq!(
39 h,
40 "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
41 );
42 }
43
44 #[test]
45 fn test_verify_sha256() {
46 let h = hash_sha256("hello");
47 assert!(verify_sha256("hello", &h));
48 assert!(!verify_sha256("world", &h));
49 }
50
51 #[test]
52 fn test_generate_token() {
53 let t = generate_token(32);
54 assert!(!t.is_empty());
55 }
56
57 #[test]
58 fn test_secure_compare() {
59 assert!(secure_compare("test", "test"));
60 assert!(!secure_compare("test", "Test"));
61 }
62}