Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert a string to hex in Rust?

I want to convert a string of characters (a SHA256 hash) to hex 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 this is true; it looks like it's only implemented for [u8].

What am I to do? Is there no method implemented to convert from a string to hex in Rust?

My Cargo.toml dependencies:

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

edit I just realized the string is already in hex format from the rust-crypto library. D'oh.

like image 435
leshow Avatar asked Dec 15 '14 20:12

leshow


People also ask

Can we convert string to hex?

Initialize final Hex string as empty. Consider every character from input, cast it into integer. This integer value is ascii value of that character. Change this integer value into hexadecimal value and add this hexadecimal value to final Hex string.

How do you convert strings to u32 in Rust?

To convert a string to an integer in Rust, use parse() function. The parse function needs to know what type, which can be specified on the left-side of assignment like so: let str = "123"; let num: i32 = str. parse().


2 Answers

Thanks to the user jey in the ##rust irc channel in freenode. You can just use the hex representation fmt provides,

>> 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"
>> 

or a bit silly one,

>> "hello world".as_bytes().iter().map(|x| format!("{:02x}", x)).collect::<String>()
"68656c6c6f20776f726c64"
like image 148
han solo Avatar answered Sep 29 '22 17:09

han solo


I will go out on a limb here, and suggest that the solution is for hash to be of type Vec<u8>.


The issue is that while you can indeed convert a String to a &[u8] using as_bytes and then use to_hex, you first need to have a valid String object to start with.

While any String object can be converted to a &[u8], the reverse is not true. A String object is solely meant to hold a valid UTF-8 encoded Unicode string: not all bytes pattern qualify.

Therefore, it is incorrect for gen_sha256 to produce a String. A more correct type would be Vec<u8> which can, indeed, accept any bytes pattern. And from then on, invoking to_hex is easy enough:

hash.as_slice().to_hex()
like image 42
Matthieu M. Avatar answered Sep 29 '22 16:09

Matthieu M.