2015-02-05 28 views
-3

我使用https://github.com/DaGenix/rust-crypto並有一些奇怪的錯誤:在加密的參數類型不匹配:: HMAC :: HMAC ::新

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()具有相同的類型?

回答

4

Doesn't Sha256::new() have the same type as Sha384::new() and 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。

+0

**否。它們是非常明顯不同的類型,如果你看源代碼,不要指望編譯器告訴你它們是不同的類型。** - 它們都**實現Digest和Hmac :: new()'接受的特性'Digest'也是。他們怎麼可能是一個不同的類型? –

+0

https://github.com/DaGenix/rust-crypto/blob/master/src/sha2.rs –

+5

@AlexanderSupertramp:他們實現共同的特質是無關緊要的:他們是不同的類型。所有的內置整數實現'Int',但它們仍然是不同的類型。 「Digest」特徵只是與多種不同類型進行交互的通用界面。 –