Skip to main content

rok_utils/data/
hashing.rs

1#[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}