next_web_utils/
digester.rs1use std::io::Read;
2use std::path::Path;
3use std::fs::File;
4use std::string::String;
5use std::vec::Vec;
6use md2::Md2;
7use md5;
8use sha1::Sha1;
9use sha2::{Sha256, Sha384, Sha512, Digest};
10
11#[derive(Debug, Clone, Copy)]
15pub enum HashAlgorithm {
16 Md2,
20 Md5,
24 Sha1,
28 Sha256,
32 Sha384,
36 Sha512,
40}
41
42pub trait Digester {
46 fn hash(&self, algorithm: HashAlgorithm) -> String;
56}
57
58impl Digester for String {
59 fn hash(&self, algorithm: HashAlgorithm) -> String {
60 self.as_bytes().hash(algorithm)
61 }
62}
63
64impl Digester for &[u8] {
65 fn hash(&self, algorithm: HashAlgorithm) -> String {
66 match algorithm {
67 HashAlgorithm::Md2 => {
68 let mut hasher = Md2::new();
69 hasher.update(self);
70 format!("{:x}", hasher.finalize())
71 }
72 HashAlgorithm::Md5 => {
73 let digest = md5::compute(self);
74 format!("{:x}", digest)
75 }
76 HashAlgorithm::Sha1 => {
77 let mut hasher = Sha1::new();
78 hasher.update(self);
79 format!("{:x}", hasher.finalize())
80 }
81 HashAlgorithm::Sha256 => {
82 let mut hasher = Sha256::new();
83 hasher.update(self);
84 format!("{:x}", hasher.finalize())
85 }
86 HashAlgorithm::Sha384 => {
87 let mut hasher = Sha384::new();
88 hasher.update(self);
89 format!("{:x}", hasher.finalize())
90 }
91 HashAlgorithm::Sha512 => {
92 let mut hasher = Sha512::new();
93 hasher.update(self);
94 format!("{:x}", hasher.finalize())
95 }
96 }
97 }
98}
99
100impl Digester for Vec<u8> {
101 fn hash(&self, algorithm: HashAlgorithm) -> String {
102 self.as_slice().hash(algorithm)
103 }
104}
105
106impl Digester for File {
107 fn hash(&self, algorithm: HashAlgorithm) -> String {
108 let mut buffer = Vec::new();
109 let mut file = self.try_clone().unwrap();
110 file.read_to_end(&mut buffer).unwrap();
111 buffer.hash(algorithm)
112 }
113}
114
115pub fn hash_file<P: AsRef<Path>>(path: P, algorithm: HashAlgorithm) -> std::io::Result<String> {
137 let file = File::open(path)?;
138 Ok(file.hash(algorithm))
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
149 fn test_string_hash() {
150 let text = "Hello, World!".to_string();
151 let md5_hash = text.hash(HashAlgorithm::Md5);
152 assert_eq!(md5_hash, "65a8e27d8879283831b664bd8b7f0ad4");
153
154 let sha256_hash = text.hash(HashAlgorithm::Sha256);
155 assert_eq!(sha256_hash, "dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f");
156 }
157
158 #[test]
162 fn test_bytes_hash() {
163 let bytes = vec![1, 2, 3, 4, 5];
164 let md5_hash = bytes.hash(HashAlgorithm::Md5);
165 assert_eq!(md5_hash, "7cfdd07889b3295d6a550914ab35e068");
166
167 let sha1_hash = bytes.hash(HashAlgorithm::Sha1);
168 assert_eq!(sha1_hash, "8f9baf15c0c6aa4887d832e415735772a5a05a5c");
169 }
170}