diff --git a/Cargo.toml b/Cargo.toml index b859e0a..b8ad27a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ crate-type = ["dylib", "rlib"] aes = "0.8.3" base64 = "0.21.2" blake2b_simd = "1.0.3" +blake3 = { version = "1.8.2", features = ["serde", "digest"] } blockhash = "0.5.0" cbc = { version = "0.1.2", features = ["std"] } chrono = "0.4.26" diff --git a/src/hash/blake3/mod.rs b/src/hash/blake3/mod.rs new file mode 100644 index 0000000..bb1f3d7 --- /dev/null +++ b/src/hash/blake3/mod.rs @@ -0,0 +1,109 @@ +use blake3::Hasher; +use std::fs::File; +use std::io::{Read, Result as IoResult}; +use std::path::Path; + +/// 计算给定字节数组的Blake3/512校验和,返回字节数组。 +pub fn blake3(data: &[u8]) -> Vec { + let mut hasher = Hasher::new(); + hasher.update(data); + let mut out = vec![0u8, 64]; + hasher.finalize_xof().fill(&mut out); + out +} + +/// 计算给定字节数组的Blake3/256校验和,返回字节数组。 +pub fn blake3_256(data: &[u8]) -> Vec { + let mut hasher = Hasher::new(); + hasher.update(data); + hasher.finalize().as_bytes().to_vec() +} + +/// 计算给定字节数组的Blake3/384校验和,返回字节数组。 +pub fn blake3_384(data: &[u8]) -> Vec { + let mut hasher = Hasher::new(); + hasher.update(data); + let mut out = vec![0u8, 48]; + hasher.finalize_xof().fill(&mut out); + out +} + +/// 计算给定字节数组的Blake3/224校验和,返回字节数组。 +pub fn blake3_224(data: &[u8]) -> Vec { + let mut hasher = Hasher::new(); + hasher.update(data); + let mut out = vec![0u8, 28]; + hasher.finalize_xof().fill(&mut out); + out +} + +/// 计算给定字节数组的Blake3校验和,返回十六进制字符串。 +pub fn blake3_hex(data: &[u8]) -> String { + hex::encode(blake3(data)) +} + +/// 计算给定字节数组的Blake3/256校验和,返回十六进制字符串。 +pub fn blake3_256_hex(data: &[u8]) -> String { + hex::encode(blake3_256(data)) +} + +/// 计算给定字节数组的Blake3/384校验和,返回十六进制字符串。 +pub fn blake3_384_hex(data: &[u8]) -> String { + hex::encode(blake3_384(data)) +} + +/// 计算给定字节数组的Blake3/224校验和,返回十六进制字符串。 +pub fn blake3_224_hex(data: &[u8]) -> String { + hex::encode(blake3_224(data)) +} + +/// 根据给定位数计算一个字节数组的Blake3校验和,返回字节数组。 +pub fn sum(data: &[u8], bit_size: Option) -> Vec { + match bit_size { + Some(bit_size) => match bit_size { + 224 => blake3_224(data), + 256 => blake3_256(data), + 384 => blake3_384(data), + 512 | _ => blake3(data), + }, + None => blake3(data), + } +} + +/// 根据给定位数计算一个字节数组的Blake3校验和,返回十六进制字符串。 +pub fn sum_hex(data: &[u8], bit_size: Option) -> String { + hex::encode(sum(data, bit_size)) +} + +/// 根据给定位数计算一个文件的Blake3校验和,返回字节数组。 +pub fn sum_file>(file: P, bit_size: Option) -> IoResult> { + let mut f = File::open(file)?; + let mut hasher = Hasher::new(); + + let mut buffer = [0; 8192]; + loop { + let bytes_read = f.read(&mut buffer)?; + if bytes_read == 0 { + break; + } + hasher.update(&buffer[..bytes_read]); + } + + let mut out = match bit_size { + Some(bit_size) => match bit_size { + 224 => vec![0u8, 28], + 256 => vec![0u8, 32], + 384 => vec![0u8, 48], + 512 | _ => vec![0u8, 64], + }, + None => vec![0u8, 64], + }; + hasher.finalize_xof().fill(&mut out); + Ok(out) +} + +/// 根据给定位数计算一个文件的Blake3校验和,返回十六进制字符串。 +pub fn sum_file_hex>(file: P, bit_size: Option) -> IoResult { + let hash = sum_file(file, bit_size)?; + Ok(hex::encode(hash)) +} diff --git a/src/hash/mod.rs b/src/hash/mod.rs index 5ec8bc7..6c314ba 100644 --- a/src/hash/mod.rs +++ b/src/hash/mod.rs @@ -95,3 +95,4 @@ pub mod image_hash { } pub mod blake2b; +pub mod blake3;