crypto :: hmac :: Hmac :: new中的参数类型不匹配

时间:2015-02-05 06:16:20

标签: rust

我正在使用https://github.com/DaGenix/rust-crypto并遇到一些奇怪的错误:

extern crate crypto;
use crypto::sha2::{Sha256, Sha384, Sha512};
use crypto::hmac::Hmac;
use crypto::digest::Digest;
use crypto::mac::Mac;


enum MyType {
  Type1,
  Type2,
  Type3
}

//......

let mut hmac = Hmac::new(match myType {
   MyType::Type1 => Sha256::new(),
   MyType::Type2 => Sha384::new(),
   MyType::Type3 => Sha512::new()
  }, my_secret.to_string().as_bytes()
);

错误是:

error: match arms have incompatible types:
 expected `crypto::sha2::Sha256`,
    found `crypto::sha2::Sha384`
(expected struct `crypto::sha2::Sha256`,
    found struct `crypto::sha2::Sha384`) [E0308]
   let mut hmac = Hmac::new(match algorithm {
       MyType::Type1 => Sha256::new(),
       MyType::Type2 => Sha384::new(),
       MyType::Type3 => Sha512::new(),
       _ => panic!()
     }, secret.to_string().as_bytes()
 note: match arm with an incompatible type
       MyType::Type2 => Sha384::new(),
                                         ^~~~~~~~~~~~~
 help: methods from traits can only be called if the trait is implemented and in scope; the following traits define a method `input`, perhaps you need to implement one of them:
 help: candidate #1: `crypto::cryptoutil::FixedBuffer`
 help: candidate #2: `crypto::digest::Digest`
 help: candidate #3: `crypto::mac::Mac`
 help: methods from traits can only be called if the trait is implemented and in scope; the following traits define a method `result`, perhaps you need to implement one of them:
 help: candidate #1: `crypto::digest::Digest`
 help: candidate #2: `crypto::mac::Mac`

为什么? Sha256::new()Sha384::new()Sha512::new()的类型不相同吗?

1 个答案:

答案 0 :(得分:5)

  

Sha256::new()Sha384::new()Sha512::new()的类型不同吗?

没有。如果你查看源代码,他们非常清楚地不同的类型,永远不要让编译器告诉你他们是不同的类型。

除此之外,您还尝试在单个表达式中创建三种不同类型的Hmac之一,不可能。如果你看一下源代码中的定义,你会看到

impl <D: Digest> Hmac<D> {
    // ...
    pub fn new(mut digest: D, key: &[u8]) -> Hmac<D> {
        // ...
    }
    // ...
}

也就是说,每种可能的Hmac类型都有不同的Digest类型。

您需要通过某种动态调度才能实现此功能。例如:

let (hmac_sha256, hmac_sha384, hmac_sha512);
let mac: &mut crypto::mac::Mac = match myType {
    MyType::Type1 => {
        hmac_sha256 = Hmac::new(Sha256::new(), my_secret.to_string().as_bytes();
        &mut hmac_sha256 as &mut crypto::mac::Mac
    },
    // ...
};

如果引用不起作用,您可以使用Box es。