简体   繁体   English

如何更改此功能的返回类型?

[英]How can I change the return type of this function?

I'm going through the matasano crypto challenges using rust, with rust-crypto for the AES implementation. 我正在通过使用rust的matasano加密挑战 ,以及用于AES实现的rust-crypto。 I have this function to do basic ECB mode encryption (basically taken nearly verbatim from the rust-crypto repository's example ): 我有这个功能来进行基本的ECB模式加密(基本上从rust-crypto存储库的例子中逐字逐句):

pub fn aes_enc_ecb_128(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut encryptor = aes::ecb_encryptor(
            aes::KeySize::KeySize128,
            key,
            blockmodes::NoPadding);
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = encryptor.encrypt(&mut read_buffer,
                                       &mut write_buffer,
                                       true);

        final_result.extend(write_buffer
                            .take_read_buffer()
                            .take_remaining().iter().map(|&i| i));
        match result {
            Ok(BufferResult::BufferUnderflow) => break,
            Ok(_) => {},
            Err(e) => return Err(e)
        }
    }

    Ok(final_result)
}

The above version compiles with no problem, and works as expected. 上面的版本编译没有问题,并按预期工作。 However, to make it fit with the rest of my error handling scheme I'd like to change the return type to Result<Vec<u8>,&'static str> . 但是,为了使其适合我的错误处理方案的其余部分,我想将返回类型更改为Result<Vec<u8>,&'static str> This is the function with that change applied: 这是应用该更改的功能:

pub fn aes_enc_ecb_128(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, &'static str> {
    let mut encryptor = aes::ecb_encryptor(
            aes::KeySize::KeySize128,
            key,
            blockmodes::NoPadding);
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = encryptor.encrypt(&mut read_buffer,
                                       &mut write_buffer,
                                       true);

        final_result.extend(write_buffer
                            .take_read_buffer()
                            .take_remaining().iter().map(|&i| i));
        match result {
            Ok(BufferResult::BufferUnderflow) => break,
            Ok(_) => {},
            Err(_) => return Err("Encryption failed")
        }
    }

    Ok(final_result)
}

When I attempt to compile this version, I get the following error (paths removed for clarity): 当我尝试编译此版本时,我收到以下错误(为清晰起见,删除了路径):

error: source trait is private
         let result = encryptor.encrypt(&mut read_buffer,
                                        &mut write_buffer,
                                        true);
error: source trait is private
let r = decryptor.decrypt(&mut read_buffer, &mut write_buffer, true);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The only way I've been able to change this type is to wrap the original function in a conversion function like this: 我能够改变这种类型的唯一方法是将原始函数包装在这样的转换函数中:

pub fn converted_enc(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, &'static str> {
   match aes_enc_ecb_128(key,data) {
       Ok(v) => Ok(v),
       Err(_) => Err("Encryption failed")
   } 
}

What should I do instead of the above in order to get the return value to fit with the rest of my API, and why is the more direct method failing? 为了使返回值适合我的其余API,我应该做什么而不是上面的内容,为什么更直接的方法失败?

I'm using the following versions of rust/cargo: 我使用以下版本的锈/货:

rustc 1.2.0-nightly (0cc99f9cc 2015-05-17) (built 2015-05-18)
cargo 0.2.0-nightly (ac61996 2015-05-17) (built 2015-05-17)

I think you have come across a bug of the compiler. 我想你遇到过编译器的错误。 Your code should compile 你的代码应该编译

You can use crypto::symmetriccipher::Encryptor; 你可以use crypto::symmetriccipher::Encryptor; as a workaround: 作为一种解决方法:

pub fn aes_enc_ecb_128(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, &'static str> {
    use crypto::symmetriccipher::Encryptor;
    let mut encryptor = aes::ecb_encryptor(
            aes::KeySize::KeySize128,
            key,
            blockmodes::NoPadding);
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = encryptor.encrypt(&mut read_buffer,
                                       &mut write_buffer,
                                       true);

        final_result.extend(write_buffer
                            .take_read_buffer()
                            .take_remaining().iter().map(|&i| i));
        match result {
            Ok(BufferResult::BufferUnderflow) => break,
            Ok(_) => {},
            Err(_) => return Err("Encryption failed")
        }
    }

    Ok(final_result)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM