【问题标题】:How to hash a string using the sodiumoxide crate?如何使用氧化钠板条箱对字符串进行哈希处理?
【发布时间】:2017-10-13 14:28:15
【问题描述】:

我正在尝试使用sodiumoxide 提供的SHA256 哈希函数来编写hash_string 函数。这个函数应该接受一个字符串并返回字符串的哈希值。

这是我目前所拥有的:

extern crate sodiumoxide;

use std::string::String;
use sodiumoxide::crypto::hash::sha256;

pub fn hash_string(s: String) -> String {
    let digest = sha256::hash(&s.into_bytes());
    String::from_utf8_unchecked(digest).to_owned()
}

显然这不正确,但我不知道如何解决。

我能够使用rust-crypto crate 实现这一点。

pub fn hash_string(input: String) -> String {
    let mut sha = Sha256::new();
    sha.input_str(&input);
    sha.result_str()
}

我想完全按照上面的方法做,但改用氧化钠板条箱。

【问题讨论】:

  • 请说明您认为不正确的原因。你测试过这个功能吗?您使用了哪些输入(可能具有已知的预期输出)?
  • 它无法编译,所以我无法测试该功能。我不知道如何将digest 转换为字符串。
  • 假设您理解哈希只是一个字节向量,很明显将它们解释为 UTF-8 字符串是错误的。您可能希望将其转换为文本表示形式(十六进制、Base64 等)。同样,您能否提供输入和预期输出?
  • 能否提供编译错误?
  • 您是如何从一组字节中得出该字符序列的?您是否可能使用过诸如“(十六进制,Base64 等)”之类的算法?或许您愿意与我们分享该算法

标签: hash cryptography rust


【解决方案1】:

从您链接的文档中,Digest 定义为:

pub struct Digest(pub [u8; 32]);

您可以使用元组索引表示法访问这些字节:foo.0。它还实现了AsRef<[u8]>

然后您可以只使用现有答案之一将切片转换为十六进制,例如Show u8 slice in hex representation 中的答案。

extern crate sodiumoxide;

use sodiumoxide::crypto::hash::sha256;
use std::fmt;

pub fn hash_string(s: &str) -> String {
    let digest = sha256::hash(s.as_bytes());
    format!("{:X}", HexSlice::new(&digest))
}

struct HexSlice<'a>(&'a [u8]);

impl<'a> HexSlice<'a> {
    fn new<T>(data: &'a T) -> HexSlice<'a>
        where T: ?Sized + AsRef<[u8]> + 'a
    {
        HexSlice(data.as_ref())
    }
}

impl<'a> fmt::UpperHex for HexSlice<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for byte in self.0 {
            // Decide if you want upper- or lowercase results,
            // padding the values to two characters, spaces
            // between bytes, etc.
            write!(f, "{:X}", byte)?;
        }
        Ok(())
    }
}

fn main() {
    let h = hash_string("hello world");
    println!("{}", h);
}

请注意,获取拥有的 String 没有任何好处,因为我们不使用分配。

【讨论】:

  • 请注意,write!(f, "{:X}", byte) 仅在字节值小于 16 时写入一位。当以十六进制打印散列时,您通常希望以 2 位打印每个字节。这就是hex crate 正在做的事情。
  • @LukasKalbertodt 是的!链接的问题/答案讨论了这些细微差别(还有上/下、字节之间的填充等)
猜你喜欢
  • 2014-05-13
  • 1970-01-01
  • 2011-04-25
  • 2021-09-19
  • 2018-11-08
  • 2011-08-24
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
相关资源
最近更新 更多