我需要将&[u8]
转换为十六进制表示。例如[ A9, 45, FF, 00 ... ]
。
切片未实现特征std::fmt::UpperHex
(因此我无法使用std::fmt::format
)。 Rust具有serialize::hex::ToHex
特征,它将&[u8]
转换为十六进制字符串,但我需要一个具有单独字节的表示。
我可以自己为UpperHex
实现特质&[u8]
,但我不确定这是多么规范。这样做最规范的方法是什么?
答案 0 :(得分:28)
可以使用:x?
“使用十六进制整数进行调试”格式化程序:
let data = b"hello";
println!("{:x?}", data);
println!("{:X?}", data);
[68, 65, 6c, 6c, 6f]
[68, 65, 6C, 6C, 6F]
它也可以与pretty修饰符结合使用:
let data = b"hello";
println!("{:#x?}", data);
println!("{:#X?}", data);
[
0x68,
0x65,
0x6c,
0x6c,
0x6f
]
[
0x68,
0x65,
0x6C,
0x6C,
0x6F
]
如果您需要更多控制或需要支持旧版本的Rust,请继续阅读。
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);
}
这可以通过在结构上实现其中一个格式特征(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>
}
答案 1 :(得分:5)
由于接受的答案对Rust 1.0稳定不起作用,这是我的尝试。应该是无分配的,因此速度相当快。这基本上是[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(())
}
}
用法:
let buff = [0_u8; 24];
println!("{:x}", ByteBuf(&buff));
答案 2 :(得分:1)
有一个箱子:hex-slice。
例如:
extern crate hex_slice;
use hex_slice::AsHex;
fn main() {
let foo = vec![0u32, 1, 2 ,3];
println!("{:02x}", foo.as_hex());
}