Rust · 1413 bytes Raw Blame History
1 //! Content hashing for clipboard deduplication
2
3 use sha2::{Digest, Sha256};
4
5 /// Compute SHA256 hash of clipboard content
6 pub fn compute_hash(data: &[u8]) -> String {
7 let mut hasher = Sha256::new();
8 hasher.update(data);
9 format!("SHA256:{}", hex::encode(hasher.finalize()))
10 }
11
12 /// Quick hash from first N bytes + length for large content
13 /// Useful for quick deduplication check before transferring
14 #[allow(dead_code)]
15 pub fn compute_quick_hash(data: &[u8], size: u64) -> String {
16 const SAMPLE_SIZE: usize = 4096;
17 let mut hasher = Sha256::new();
18 hasher.update(&data[..data.len().min(SAMPLE_SIZE)]);
19 hasher.update(size.to_le_bytes());
20 format!("SHA256-QUICK:{}", hex::encode(hasher.finalize()))
21 }
22
23 #[cfg(test)]
24 mod tests {
25 use super::*;
26
27 #[test]
28 fn test_compute_hash() {
29 let data = b"Hello, World!";
30 let hash = compute_hash(data);
31 assert!(hash.starts_with("SHA256:"));
32 assert_eq!(hash.len(), 7 + 64); // "SHA256:" + 64 hex chars
33 }
34
35 #[test]
36 fn test_same_content_same_hash() {
37 let data1 = b"test content";
38 let data2 = b"test content";
39 assert_eq!(compute_hash(data1), compute_hash(data2));
40 }
41
42 #[test]
43 fn test_different_content_different_hash() {
44 let data1 = b"test content 1";
45 let data2 = b"test content 2";
46 assert_ne!(compute_hash(data1), compute_hash(data2));
47 }
48 }
49