You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建基于match或enum自动匹配填充对应hash类型的Rust函数

Rust根据flag参数动态选择哈希算法实现方案

你定义的create_hash是泛型函数,泛型参数为编译期静态分发,无法直接将运行时传入的flag变量映射为编译期类型,可通过以下两种方案实现需求:


方案1:调用处直接匹配flag(无额外封装,实现最简单)

直接在generate_string_hash函数中对flag做分支匹配,每个分支传入对应哈希算法的实例即可,原有create_hash函数无需修改:

// 提前引入依赖的哈希算法
use sha1::Sha1;
use sha2::{Sha256, Sha512};
use libc::{c_char, i32};
use std::ffi::{CStr, CString};

// 提前约定flag取值对应哈希类型:
// 0 -> SHA1
// 1 -> SHA256
// 2 -> SHA512
#[no_mangle]
pub extern "C" fn generate_string_hash(hashptr: *mut c_char, flag: u8, result_ptr: *mut i32) {
    unsafe {
        if SW == 0 { return(); }
    }
    let chash: &CStr = unsafe { CStr::from_ptr(hashptr) };
    let msg = chash.to_str().expect("输入字符串不是合法UTF-8格式");
    // 运行时匹配flag生成对应哈希实例
    let hash_res = match flag {
        0 => cryptography::create_hash(msg, Sha1::default()),
        1 => cryptography::create_hash(msg, Sha256::default()),
        2 => cryptography::create_hash(msg, Sha512::default()),
        _ => panic!("不支持的哈希类型flag:{}", flag) // 生产环境建议替换为返回错误码
    };
    unsafe {
        *result_ptr = CString::new(hash_res).unwrap().into_raw() as i32;
    }
}
    
// 原有create_hash无需修改
fn create_hash<D>(msg: &str, mut hasher: D) -> String
where
    D: Digest,
    digest::Output<D>: std::fmt::LowerHex,
{
    hasher.update(msg);
    format!("{:x}", hasher.finalize())
}

方案2:枚举包装哈希算法统一接口(适合哈希类型多、需要复用的场景)

如果支持的哈希类型很多,或者需要多处调用create_hash,可以用枚举封装所有支持的哈希算法,为枚举实现Digest特征后即可统一传参:

// 定义枚举包装所有支持的哈希算法
enum HasherSelector {
    Sha1(Sha1),
    Sha256(Sha256),
    Sha512(Sha512),
}

// 为枚举实现Digest特征,方法全部转发到内部的实际哈希实例
impl Digest for HasherSelector {
    type Output = String;

    fn update(&mut self, data: &[u8]) {
        match self {
            HasherSelector::Sha1(h) => h.update(data),
            HasherSelector::Sha256(h) => h.update(data),
            HasherSelector::Sha512(h) => h.update(data),
        }
    }

    fn finalize(self) -> Self::Output {
        match self {
            HasherSelector::Sha1(h) => format!("{:x}", h.finalize()),
            HasherSelector::Sha256(h) => format!("{:x}", h.finalize()),
            HasherSelector::Sha512(h) => format!("{:x}", h.finalize()),
        }
    }

    fn finalize_reset(&mut self) -> Self::Output {
        match self {
            HasherSelector::Sha1(h) => format!("{:x}", h.finalize_reset()),
            HasherSelector::Sha256(h) => format!("{:x}", h.finalize_reset()),
            HasherSelector::Sha512(h) => format!("{:x}", h.finalize_reset()),
        }
    }

    fn reset(&mut self) {
        match self {
            HasherSelector::Sha1(h) => h.reset(),
            HasherSelector::Sha256(h) => h.reset(),
            HasherSelector::Sha512(h) => h.reset(),
        }
    }

    fn output_size() -> usize { 64 }
}

封装后generate_string_hash的调用逻辑可简化为:

let hasher = match flag {
    0 => HasherSelector::Sha1(Sha1::default()),
    1 => HasherSelector::Sha256(Sha256::default()),
    2 => HasherSelector::Sha512(Sha512::default()),
    _ => panic!("不支持的哈希类型flag:{}", flag)
};
let hash_res = cryptography::create_hash(msg, hasher);

注意事项

  • 你原有代码中调用create_hash时多传入了flag参数,和函数定义的入参数量不符,属于笔误需要删除
  • 你通过into_raw()返回的C字符串是Rust堆分配的内存,C端使用完后必须调用Rust侧导出的释放函数回收,否则会出现内存泄漏
  • 非法flag的分支建议替换为返回错误码写入result_ptr,不要直接panic,避免C端程序直接崩溃

内容的提问来源于stack exchange,提问作者silak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:06:01