将十六进制的固定长度Vec <u8>转换为int </u8>

时间:2015-01-18 21:31:31

标签: rust

如何将固定长度Vec<u8>的十六进制字符转换为u32

let input: Vec<u8> = vec!['b','e','e','f']; // Pretend this works
let output: u32 = // Do some magic (Probably with serialize)
assert!(0xbeef == output);

1 个答案:

答案 0 :(得分:4)

这可能不是最有效的方式,但可能是最明显的方式。首先将字节转换为字符串,然后将该字符串转换为数字:

Rust 1.0

fn main() {
    let input: Vec<u8> = b"beef"[..].to_owned();
    let s = String::from_utf8(input).unwrap();
    let v = u32::from_str_radix(&s, 16).unwrap();
    println!("{:x}", v);
    assert!(0xbeef == v);
}

原创

use std::num;

fn main() {
    let input: Vec<u8> = vec!['b' as u8, 'e' as u8, 'e' as u8, 'f' as u8];
    let s = String::from_utf8(input).unwrap();
    let v: u32 = num::from_str_radix(&*s, 16).unwrap();
    println!("{:x}", v);
    assert!(0xbeef == v);
}
  

有没有办法用serialize执行此操作?

不是我知道的。序列化具有FromHex,可将&str转换为Vec<u8>。那么你仍然必须以某种方式将这些字节转换为数字:

extern crate serialize;
use serialize::hex::FromHex;

fn main() {
    let input: Vec<u8> = vec!['b' as u8, 'e' as u8, 'e' as u8, 'f' as u8];
    let s = String::from_utf8(input).unwrap();
    let bytes: Vec<u8> = s.from_hex().unwrap();

    let v = bytes.into_iter().fold(0u32, |val, byte| val << 8 | byte as u32);

    println!("{:x}", v);
    assert!(0xbeef == v);
}

此时,将代码点直接转换为数字并自行完成总结可能更容易:

fn dehex(c: u8) -> u8 {
    match c {
        b'0'...b'9' => c - b'0',
        b'a'...b'f' => c - b'a' + 10,
        b'A'...b'F' => c - b'A' + 10,
        _ => panic!("Do something better here"),
    }
}

fn main() {
    let input: Vec<u8> = vec![b'b', b'e', b'e', b'f'];
    let v = input.into_iter().fold(0u32, |val, char| (val << 4) | dehex(char) as u32);
    println!("{:x}", v);
    assert!(0xbeef == v);
}