I have a string that looks like this "090A0B0C"
and I would like to convert it to a slice that looks something like this [9, 10, 11, 12]
. How would I best go about doing that?
I don't want to convert a single hex char tuple to a single integer value. I want to convert a string consisting of multiple hex char tuples to a slice of multiple integer values.
You could use the hex crate for that. The decode function looks like it does what you want:
extern crate hex;
fn main() {
let input = "090A0B0C";
let decoded = hex::decode(input).expect("Decoding failed");
println!("{:?}", decoded);
}
The above will print [9, 10, 11, 12]
. Note that decode
returns a heap allocated Vec<u8>
, if you want to decode into an array you'd want to use the decode_to_slice
function, which is not yet released on crates.io or the FromHex
trait:
extern crate hex;
use hex::FromHex;
fn main() {
let input = "090A0B0C";
let decoded = <[u8; 4]>::from_hex(input).expect("Decoding failed");
println!("{:?}", decoded);
}
You can also implement hex encoding and decoding yourself, in case you want to avoid the dependency on the hex
crate:
use std::{fmt::Write, num::ParseIntError};
pub fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
(0..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16))
.collect()
}
pub fn encode_hex(bytes: &[u8]) -> String {
let mut s = String::with_capacity(bytes.len() * 2);
for &b in bytes {
write!(&mut s, "{:02x}", b);
}
s
}
Note that the decode_hex()
function panics if the string length is odd. I've made a version with better error handling and an optimised encoder available on the playground.