From 0697e61f35a84e989ec7f78527a1c99aa757a648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Thu, 9 Oct 2025 11:18:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(hash):=20=E6=B7=BB=E5=8A=A0=20Blake2b=20?= =?UTF-8?q?=E5=93=88=E5=B8=8C=E7=AE=97=E6=B3=95=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 blake2b 模块,提供多种长度的 Blake2b 哈希计算功能, 包括 224、256、384 和 512 位版本,并支持对字节数组和文件进行哈希计算。 同时支持返回字节数组和十六进制字符串两种格式。 在 Cargo.toml 中添加了 blake2b_simd 依赖以实现该功能。 --- Cargo.toml | 1 + src/hash/blake2b/mod.rs | 97 +++++++++++++++++++++++++++++++++++++++++ src/hash/mod.rs | 2 + 3 files changed, 100 insertions(+) create mode 100644 src/hash/blake2b/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 8abf500..b859e0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["dylib", "rlib"] [dependencies] aes = "0.8.3" base64 = "0.21.2" +blake2b_simd = "1.0.3" blockhash = "0.5.0" cbc = { version = "0.1.2", features = ["std"] } chrono = "0.4.26" diff --git a/src/hash/blake2b/mod.rs b/src/hash/blake2b/mod.rs new file mode 100644 index 0000000..05f0c24 --- /dev/null +++ b/src/hash/blake2b/mod.rs @@ -0,0 +1,97 @@ +use blake2b_simd::{blake2b as blake2b_hasher, Params, State}; +use std::fs::File; +use std::io::{self, Read}; +use std::path::Path; + +/// 根据给定的位数返回一个Blake2b散列实例。 +fn hasher_select(bit_size: usize) -> State { + match bit_size { + 224 => Params::new().hash_length(28).to_state(), // 224 bits = 28 bytes + 384 => Params::new().hash_length(48).to_state(), // 384 bits = 48 bytes + 512 => Params::new().hash_length(64).to_state(), // 512 bits = 64 bytes + 256 | _ => Params::new().hash_length(32).to_state(), // 256 bits = 32 bytes + } +} + +/// 计算给定字节数组的Blake2b校验和,返回字节数组。 +pub fn blake2b(data: &[u8]) -> Vec { + blake2b_hasher(data).as_bytes().to_vec() +} + +/// 计算给定字节数组的Blake2b/256校验和,返回字节数组。 +pub fn blake2b_256(data: &[u8]) -> Vec { + let mut hasher = hasher_select(256); + hasher.update(data); + hasher.finalize().as_bytes().to_vec() +} + +/// 计算给定字节数组的Blake2b/384校验和,返回字节数组。 +pub fn blake2b_384(data: &[u8]) -> Vec { + let mut hasher = hasher_select(384); + hasher.update(data); + hasher.finalize().as_bytes().to_vec() +} + +/// 计算给定字节数组的Blake2b/224校验和,返回字节数组。 +pub fn blake2b_224(data: &[u8]) -> Vec { + let mut hasher = hasher_select(224); + hasher.update(data); + hasher.finalize().as_bytes().to_vec() +} + +/// 计算给定字节数组的Blake2b校验和,返回十六进制字符串。 +pub fn blake2b_hex(data: &[u8]) -> String { + hex::encode(blake2b(data)) +} + +/// 计算给定字节数组的Blake2b/256校验和,返回十六进制字符串。 +pub fn blake2b_256_hex(data: &[u8]) -> String { + hex::encode(blake2b_256(data)) +} + +/// 计算给定字节数组的Blake2b/384校验和,返回十六进制字符串。 +pub fn blake2b_384_hex(data: &[u8]) -> String { + hex::encode(blake2b_384(data)) +} + +/// 计算给定字节数组的Blake2b/224校验和,返回十六进制字符串。 +pub fn blake2b_224_hex(data: &[u8]) -> String { + hex::encode(blake2b_224(data)) +} + +/// 根据给定位数计算一个字节数组的Blake2b校验和,返回字节数组。 +pub fn sum(data: &[u8], bit_size: Option) -> Vec { + let size = bit_size.unwrap_or(512); + let mut hasher = hasher_select(size); + hasher.update(data); + hasher.finalize().as_bytes().to_vec() +} + +/// 根据给定位数计算一个字节数组的Blake2b校验和,返回十六进制字符串。 +pub fn sum_hex(data: &[u8], bit_size: Option) -> String { + hex::encode(sum(data, bit_size)) +} + +/// 根据给定位数计算一个文件的Blake2b校验和,返回字节数组。 +pub fn sum_file>(file_path: P, bit_size: Option) -> io::Result> { + let size = bit_size.unwrap_or(512); + let mut file = File::open(file_path)?; + let mut hasher = hasher_select(size); + + let mut buffer = [0; 8192]; + loop { + let bytes_read = file.read(&mut buffer)?; + if bytes_read == 0 { + break; + } + hasher.update(&buffer[..bytes_read]); + } + + Ok(hasher.finalize().as_bytes().to_vec()) +} + +/// 根据给定位数计算一个文件的Blake2b校验和,返回十六进制字符串。 +pub fn sum_file_hex>(file_path: P, bit_size: Option) -> io::Result { + let hash = sum_file(file_path, bit_size)?; + Ok(hex::encode(hash)) +} diff --git a/src/hash/mod.rs b/src/hash/mod.rs index c0f52fc..5ec8bc7 100644 --- a/src/hash/mod.rs +++ b/src/hash/mod.rs @@ -93,3 +93,5 @@ pub mod image_hash { } } } + +pub mod blake2b;