[英]How do I convert a string to hex in Rust?
我想在 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"
編輯我剛剛意識到該字符串已經是 rust-crypto 庫中的十六進制格式。 哦。
我將在這里嘗試一下,並建議解決方案是將hash
設為Vec<u8>
類型。
問題是,雖然您確實可以使用as_bytes
將String
轉換為&[u8]
,然后使用to_hex
,但首先需要有一個有效的String
對象。
雖然任何String
對象都可以轉換為&[u8]
,但反之則不然。 String
對象僅用於保存有效的 UTF-8 編碼的 Unicode 字符串:並非所有字節模式都符合條件。
因此, gen_sha256
生成String
是不正確的。 更正確的類型是Vec<u8>
,它確實可以接受任何字節模式。 從那時起,調用to_hex
容易了:
hash.as_slice().to_hex()
看來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()
這似乎有效。 如果有人有其他答案,我會花一些時間才能接受此解決方案。
可以使用如下函數生成十六進制表示:
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
多虧了用戶j ey
在freenode的所述##銹IRC頻道。 您可以使用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"
使用hex
crate 非常簡單:
use hex;
println!("{}", hex::encode(String("some str")));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.