Did you happen to read the book? We cover strings early because this is a common pain point.
Also, if you have something more detailed than "get strings out of libraries", I can give better advice. It's tough to tell what the actual issue is.
Did you happen to read the book? We cover strings early because this is a common pain point.
Also, if you have something more detailed than "get strings out of libraries", I can give better advice. It's tough to tell what the actual issue is.
use sha2::{Sha256, Digest};
fn main() {
let mut hasher = Sha256::new();
hasher.input(b"hello world");
let result = hasher.result();
??
}
How do I get a string with the hash value? Which chapter of which book should I read?The result of a hash is never a string, so it makes sense that you'd need another step to print it as one.
In this case, the hash ends up being raw bytes. So the question is, what are you trying to do with this hash? Being a bunch of bytes, this may not be valid UTF-8 (and in this case, is not ASCII, let alone UTF-8). One option is to encode to base64:
use sha2::{Sha256, Digest};
use base64;
fn main() {
let mut hasher = Sha256::new();
hasher.input(b"hello world");
let result = hasher.result();
let encoded = base64::encode(&result);
assert_eq!("uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=", encoded);
}
But yeah, you can't exactly "get a string" out of a random bag of bytes unless you know how you want that bag of bytes to be represented, encoding wise. That's not exactly a satisfying answer, but such are strings!EDIT: sorry I don't know which docs I was looking at, I can't find it in the current version.
There are some examples of printing output using formatting strings in the RustCrypto readme:
let hash = Blake2b::digest(b"my message");
println!("Result: {:x}", hash);
https://github.com/RustCrypto/hashes#usageIf you're looking to get the actual string value rather than just print it out, then take a look at the format macro. It uses the same format strings / traits etc as println, so wherever you see println you could drop in format instead:
let hash = Blake2b::digest(b"my message");
let text = format!("{:x}", hash);
https://doc.rust-lang.org/std/macro.format.htmlRust does have a pair of traits that can be used, Display [1] and Debug [2]. Display must be implemented manually by the author of a type, while Debug can be automatically derived if all the members of a type implement Debug. Like this:
#[derive(Debug)]
struct Foo {
}
[1] https://doc.rust-lang.org/std/fmt/trait.Display.htmlIt is unfortunate that you’ve been downvoted for asking a question.
It is unfortunate how HN is nowadays but I don’t care if I can still learn a lot from people like you.
In Rust a string is a UTF-8 sequence. Typically human readable. A byte is generally represented by the u8 type, and a collection of bytes is either an array or vector (e.g. [u8] or Vec<u8>). To create a human readable form of an object in Rust you'd typically use the Display ({} format specifier) and/or Debug traits ({:?}). A string (e.g. &str or String) is NOT a collection of bytes. There are exceptions however with OsString/OsStr representing something closer to a collection of bytes and CString/CStr representing a bag of bytes.
Your comments seem a bit XY-ish to me. What are you trying to solve by converting things to strings? For debugging or human readable output Array, Vec, and u8 all implement the Debug trait. u8 also implements UpperHex and LowerHex so you can get a hex formatted version as well (e.g. format!("{:02X}", bytes)).
For the (MD5) hash case, as others have pointed out you're looking at a base 64 encoding which you'll often have to do on your own depending on the library you're using.
Now if you're struggling with owned vs borrowed strings that's a whole other matter. You can insert some magic into your functions with generics and trait constraints and into your structures with the Cow type (clone on write).
str::from_utf8(result.as_slice())
https://docs.rs/generic-array/0.8.2/generic_array/struct.Gen...
let my_rust_string = str::from_utf8(result).unwarp()
If there is a possibility of an error, (you read it from file, network ...) you can do: let my_rust_string = match str::from_utf8(result) {
Ok(str) => str,
Err(err) => panic!("Invalid utf8: {}", err),
};
Or you can do lossy conversion (will have that question mark on chars that it cant decode) let my_rust_string = String::from_utf8_lossy(result);
edit: Ok so i read sha2 api wrong. result() is raw bytes and result_str() is hex encoded string. Above wont be much use for either. And others have already explained what to use.I just stared programming in rust several months ago, and that was my pain also, since where i live we still have some other encoding in use.
What many low-level data formats deal with are raw bytes ("byte strings" in some contexts). The output of a hasher is random binary data.
What most humans are accustomed to are some form of encoding that makes it easier to spell out the octets. Hex and base64 are common. But they are not the native representation that the machine deals with.
With almost everything being explicit in rust you need an explicit conversion from bytes to hex, base64, urlencode or some other format.
Those conversion methods (with their contract often expressed as a separate trait) may be provided by the same crate or you may have to pull them in from a different crate.
A hasher does not need to provide this itself because its output types can be enhanced by foreign traits.
The O'Reilly book is good too.