如何在 Rust 中将字符串转换为十六进制?

问题描述 投票:0回答:5

我想在 Rust 中将字符串(SHA256 哈希)转换为十六进制:

extern crate crypto;
extern crate rustc_serialize;

use rustc_serialize::hex::ToHex;
use crypto::digest::Digest;
use crypto::sha2::Sha256;

fn gen_sha256(hashme: &str) -> String {
    let mut sh = Sha256::new();
    sh.input_str(hashme);

    sh.result_str()
}

fn main() {
    let hash = gen_sha256("example");

    hash.to_hex()
}

编译器说:

error[E0599]: no method named `to_hex` found for type `std::string::String` in the current scope
  --> src/main.rs:18:10
   |
18 |     hash.to_hex()
   |          ^^^^^^

我可以看出这是真的;看起来 仅针对

[u8]
实施。

我该怎么办? Rust 中是否没有实现从字符串转换为十六进制的方法?

我的 Cargo.toml 依赖项:

[dependencies]
rust-crypto = "0.2.36"
rustc-serialize = "0.3.24"

edit我刚刚意识到该字符串是already,来自rust-crypto库的十六进制格式。哦。

type-conversion hex rust
5个回答
20
投票

我会在这里冒险,并建议解决方案是

hash
Vec<u8>
类型。


问题是,虽然您确实可以使用

String
&[u8]
转换为
as_bytes
,然后使用
to_hex
,但您首先需要有一个有效的
String
对象来开始。

虽然任何

String
对象都可以转换为
&[u8]
,但反之则不然。
String
对象仅用于保存有效的 UTF-8 编码的 Unicode 字符串:并非所有字节模式都符合条件。

因此,

gen_sha256
产生
String
是不正确的。更正确的类型是
Vec<u8>
,它确实可以接受任何字节模式。从那时起,调用
to_hex
就足够简单了:

hash.as_slice().to_hex()

5
投票

看来

ToHex
的来源有我正在寻找的解决方案。它包含一个测试:

#[test]
pub fn test_to_hex() {
    assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172");
}

我修改后的代码是:

let hash = gen_sha256("example");

hash.as_bytes().to_hex()

这似乎有效。如果有人有替代答案,我将需要一些时间才能接受此解决方案。


3
投票

可以使用如下函数生成十六进制表示:

pub fn hex_push(buf: &mut String, blob: &[u8]) {
    for ch in blob {
        fn hex_from_digit(num: u8) -> char {
            if num < 10 {
                (b'0' + num) as char
            } else {
                (b'A' + num - 10) as char
            }
        }
        buf.push(hex_from_digit(ch / 16));
        buf.push(hex_from_digit(ch % 16));
    }
}

这比当前语言中实现的通用基数格式更有效

这是一个基准

test bench_specialized_hex_push   ... bench:          12 ns/iter (+/- 0) = 250 MB/s
test bench_specialized_fomat      ... bench:          42 ns/iter (+/- 12) = 71 MB/s
test bench_specialized_format     ... bench:          47 ns/iter (+/- 2) = 63 MB/s
test bench_specialized_hex_string ... bench:          76 ns/iter (+/- 9) = 39 MB/s
test bench_to_hex                 ... bench:          82 ns/iter (+/- 12) = 36 MB/s
test bench_format                 ... bench:          97 ns/iter (+/- 8) = 30 MB/s

3
投票

感谢 freenode

##rust
irc 频道中的用户 jey。您可以只使用
fmt
提供的十六进制表示,

>> let mut s = String::new();
>> use std::fmt::Write as FmtWrite; // renaming import to avoid collision
>> for b in "hello world".as_bytes() { write!(s, "{:02x}", b); }
()
>> s
"68656c6c6f20776f726c64"
>> 

或者有点傻,

>> "hello world".as_bytes().iter().map(|x| format!("{:02x}", x)).collect::<String>()
"68656c6c6f20776f726c64"

2
投票

使用

hex
板条箱,非常简单:

use hex;
println!("{}", hex::encode(String("some str")));
© www.soinside.com 2019 - 2024. All rights reserved.