feat(hash): 添加 Blake3 哈希算法支持

新增 blake3 模块,提供多种长度的 Blake3 哈希计算功能,
包括 224、256、384 和 512 位输出格式,支持字节数组和文件输入,
并可选择返回字节数组或十六进制字符串。同时在 hash 模块中导出该功能。
This commit is contained in:
徐涛
2025-10-09 13:14:43 +08:00
parent 0697e61f35
commit 5b4dff402c
3 changed files with 111 additions and 0 deletions

View File

@@ -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"

109
src/hash/blake3/mod.rs Normal file
View File

@@ -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<u8> {
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<u8> {
let mut hasher = Hasher::new();
hasher.update(data);
hasher.finalize().as_bytes().to_vec()
}
/// 计算给定字节数组的Blake3/384校验和返回字节数组。
pub fn blake3_384(data: &[u8]) -> Vec<u8> {
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<u8> {
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<usize>) -> Vec<u8> {
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<usize>) -> String {
hex::encode(sum(data, bit_size))
}
/// 根据给定位数计算一个文件的Blake3校验和返回字节数组。
pub fn sum_file<P: AsRef<Path>>(file: P, bit_size: Option<usize>) -> IoResult<Vec<u8>> {
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<P: AsRef<Path>>(file: P, bit_size: Option<usize>) -> IoResult<String> {
let hash = sum_file(file, bit_size)?;
Ok(hex::encode(hash))
}

View File

@@ -95,3 +95,4 @@ pub mod image_hash {
}
pub mod blake2b;
pub mod blake3;