使用sha2库泛型哈希方法时,如何将GenericArray转为十六进制字符串?
解决Sha2泛型哈希格式化十六进制的编译错误
问题原因
GenericArray<u8, OutputSize>的LowerHex格式化实现要求关联类型OutputSize必须实现Add<Output = OutputSize>(用于计算十六进制字符串总长度:每个字节对应2个字符,总长度=输出大小×2)。你的泛型函数calc_hash未为T的OutputSize添加该约束,同时缺少对OutputSizeUser trait的显式引入,导致编译失败。
解决方案
方案1:添加正确的泛型约束
- 显式引入
crypto_common::OutputSizeUsertrait(sha2依赖该库,无需额外添加Cargo依赖):
use crypto_common::OutputSizeUser; use sha2::{Digest, Sha224, Sha256, Sha384, Sha512}; use std::error::Error; use std::{env, fs, io, process};
- 修改
calc_hash的泛型约束,补充OutputSize的加法运算要求:
impl AutoSha { fn calc_hash<T>(&self, file_path: String) -> Result<String, Box<dyn Error>> where T: Digest + io::Write, <T as OutputSizeUser>::OutputSize: std::ops::Add<Output = <T as OutputSizeUser>::OutputSize>, { let mut hasher = T::new(); let mut file = fs::File::open(file_path)?; io::copy(&mut file, &mut hasher)?; let hash = hasher.finalize(); Ok(format!("{:x}", hash)) } }
方案2:使用Digest内置的encode_hex方法(更简洁)
sha2的Digest trait提供了encode_hex方法,可直接将哈希结果转为十六进制字符串,无需依赖LowerHex格式化,也不需要额外泛型约束:
impl AutoSha { fn calc_hash<T: Digest + io::Write>(&self, file_path: String) -> Result<String, Box<dyn Error>> { let mut hasher = T::new(); let mut file = fs::File::open(file_path)?; io::copy(&mut file, &mut hasher)?; let hash = hasher.finalize(); Ok(hash.encode_hex()) } }
方案3:使用hex crate手动编码
若使用的sha2版本无encode_hex方法,可借助hex crate:
- 在Cargo.toml中添加依赖:
[dependencies] hex = "0.4" sha2 = "0.10"
- 修改代码实现:
use hex::encode; // ... impl AutoSha { fn calc_hash<T: Digest + io::Write>(&self, file_path: String) -> Result<String, Box<dyn Error>> { let mut hasher = T::new(); let mut file = fs::File::open(file_path)?; io::copy(&mut file, &mut hasher)?; let hash = hasher.finalize(); Ok(encode(hash)) } }
内容的提问来源于stack exchange,提问作者B1TC0R3
相关产品推荐
相关产品推荐

