以十六进制表示显示u8切片

Ale*_*ndr 23 hex slice rust

我需要转换&[u8]为十六进制表示.例如[ A9, 45, FF, 00 ... ].

std::fmt::UpperHex切片没有实现特性(所以我不能使用std::fmt::format).Rust具有serialize::hex::ToHex特征,它转换&[u8]为十六进制字符串,但我需要一个具有单独字节的表示.

我可以UpperHex&[u8]自己实现特质,但我不确定这会是多么规范.这样做最规范的方法是什么?

She*_*ter 46

Rust 1.26.0及以上

可以使用:x?"使用十六进制整数调试"格式化程序:

let data = b"hello";
println!("{:x?}", data);
println!("{:X?}", data);
Run Code Online (Sandbox Code Playgroud)
[68, 65, 6c, 6c, 6f]
[68, 65, 6C, 6C, 6F]
Run Code Online (Sandbox Code Playgroud)

它也可以与pretty修饰符结合使用:

let data = b"hello";
println!("{:#x?}", data);
println!("{:#X?}", data);
Run Code Online (Sandbox Code Playgroud)
[
    0x68,
    0x65,
    0x6c,
    0x6c,
    0x6f
]
[
    0x68,
    0x65,
    0x6C,
    0x6C,
    0x6F
]
Run Code Online (Sandbox Code Playgroud)

如果您需要更多控制或需要支持较旧版本的Rust,请继续阅读.

Rust 1.0及以上

use std::fmt::Write;

fn main() {
    let mut s = String::new();
    for &byte in "Hello".as_bytes() {
        write!(&mut s, "{:X} ", byte).expect("Unable to write");
    }

    println!("{}", s);
}
Run Code Online (Sandbox Code Playgroud)

这可以通过执行格式化的特征之一(被向上幻想fmt::Debug,fmt::Display,fmt::LowerHex,fmt::UpperHex上一个结构等),并且有一个小的构造:

use std::fmt;

struct HexSlice<'a>(&'a [u8]);

impl<'a> HexSlice<'a> {
    fn new<T>(data: &'a T) -> HexSlice<'a> 
        where T: ?Sized + AsRef<[u8]> + 'a
    {
        HexSlice(data.as_ref())
    }
}

// You can even choose to implement multiple traits, like Lower and UpperHex
impl<'a> fmt::Display for HexSlice<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for byte in self.0 {
            // Decide if you want to pad out the value here
            write!(f, "{:X} ", byte)?;
        }
        Ok(())
    }
}

fn main() {
    // To get a `String`
    let s = format!("{}", HexSlice::new("Hello"));

    // Or print it directly
    println!("{}", HexSlice::new("world"));

    // Works with 
    HexSlice::new("Hello");              // string slices (&str)
    HexSlice::new(b"Hello");             // byte slices (&[u8])
    HexSlice::new(&"World".to_string()); // References to String
    HexSlice::new(&vec![0x00, 0x01]);    // References to Vec<u8>  
}
Run Code Online (Sandbox Code Playgroud)

  • 格式字符串不应该是"{{02X}"`以确保为每个字符打印两个十六进制字符(如果需要,包括第一个"0")? (4认同)
  • @phoenix 是的,如果需要的话。这就是我所说的“决定是否要在此处填充值”的意思。 (2认同)

小智 21

hex::encode六角板条箱中使用。

let a: [u8;4] = [1, 3, 3, 7];
assert_eq!(hex::encode(&a), "01030307");
Run Code Online (Sandbox Code Playgroud)
[dependencies]
hex = "0.4"
Run Code Online (Sandbox Code Playgroud)


yeg*_*256 9

我这样做:

\n
let bytes : Vec<u8> = "\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82".to_string().as_bytes().to_vec();\nlet hex : String = bytes.iter()\n  .map(|b| format!("{:02x}", b).to_string())\n  .collect::<Vec<String>>()\n  .join(" ");\n
Run Code Online (Sandbox Code Playgroud)\n


Gol*_*nks 6

由于接受的答案不适用于Rust 1.0 stable,这是我的尝试.应该是无分配的,因此速度相当快.这基本上是[u8]的格式化程序,但由于一致性规则,我们必须换行[u8]到自定义类型ByteBuf(&[u8])才能使用它:

struct ByteBuf<'a>(&'a [u8]);

impl<'a> std::fmt::LowerHex for ByteBuf<'a> {
    fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        for byte in self.0 {
            try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
        }
        Ok(())
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let buff = [0_u8; 24];
println!("{:x}", ByteBuf(&buff));
Run Code Online (Sandbox Code Playgroud)


Gab*_*iel 6

有一个箱子:hex-slice

例如:

extern crate hex_slice;
use hex_slice::AsHex;

fn main() {
    let foo = vec![0u32, 1, 2 ,3];
    println!("{:02x}", foo.as_hex());
}
Run Code Online (Sandbox Code Playgroud)