How can I convert a string to hex in Rust?
I want to convert a character string (SHA256 hash) to a six in Rust:
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()
}
The compiler says:
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()
| ^^^^^^
I can see that it is true; it looks like it's implemented only for[u8]
.
What should I do? Is there a method that can be used to convert from string to hex in Rust?
My Cargo.toml dependencies:
[dependencies]
rust-crypto = "0.2.36"
rustc-serialize = "0.3.24"
edit I just realized that the string is already in hex from the rust-crypto library. D'o.
source to share
I'll go out to a finiteness and assume that the solution for hash
is of type Vec<u8>
.
The problem is that while you can actually convert String
to &[u8]
with as_bytes
and then use to_hex
, you first need to have a valid object String
to start with.
While any object String
can be converted to &[u8]
, the reverse is not true. The object String
is only for storing a valid UTF-8 encoded Unicode string: not all byte patterns are eligible.
Therefore, for gen_sha256
incorrectly create a String
. A more correct type would be Vec<u8>
one that can indeed accept any byte pattern. And from this point on, the call is to_hex
quite simple:
hash.as_slice().to_hex()
source to share
It looks like the source for ToHex
has the solution I'm looking for. It contains a test:
#[test]
pub fn test_to_hex() {
assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172");
}
My updated code:
let hash = gen_sha256("example");
hash.as_bytes().to_hex()
It works. I'll take some time before making this decision if anyone has an alternative answer.
source to share
Hexadecimal representation can be generated using a function like this:
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));
}
}
This is slightly more efficient than the generic radix formatting currently implemented in this language .
Here's the benchmark :
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
source to share