1const HEX_CHARS: &[u8; 16] = b"0123456789ABCDEF";
3#[inline]
4pub fn byte2hex(b: u8) -> [u8; 2] { [HEX_CHARS[(b >> 4) as usize & 0x0F], HEX_CHARS[(b & 0x0F) as usize]] }
5#[inline]
6pub fn int2hex(v: i32) -> [u8; 2] { let mut n = v; if n < 0 { n += 256; } byte2hex((n & 0xFF) as u8) }
7#[inline]
8pub fn short2hex(v: i16) -> [u8; 4] { [HEX_CHARS[((v >> 12) & 0x0F) as usize], HEX_CHARS[((v >> 8) & 0x0F) as usize], HEX_CHARS[((v >> 4) & 0x0F) as usize], HEX_CHARS[(v & 0x0F) as usize]] }
9#[inline]
10pub fn num_to_hex8(v: u16) -> [u8; 4] { [HEX_CHARS[((v >> 12) & 0x0F) as usize], HEX_CHARS[((v >> 8) & 0x0F) as usize], HEX_CHARS[((v >> 4) & 0x0F) as usize], HEX_CHARS[(v & 0x0F) as usize]] }
11pub fn hex2bytes(s: &str, out: &mut [u8]) -> Option<usize> {
12 if s.is_empty() { return None; }
13 let bytes = s.as_bytes(); let mut nibbles = [0u8; 2]; let mut ni = 0usize; let mut oi = 0usize;
14 for &b in bytes { let v = match b { b' ' | b'\t' => continue, b'0'..=b'9' => b - b'0', b'a'..=b'f' => b - b'a' + 10, b'A'..=b'F' => b - b'A' + 10, _ => return None }; nibbles[ni] = v; ni += 1; if ni == 2 { if oi >= out.len() { return None; } out[oi] = (nibbles[0] << 4) | nibbles[1]; oi += 1; ni = 0; } }
15 if ni != 0 { return None; } Some(oi)
16}
17#[cfg(test)]
18mod tests {
19 use super::*;
20 #[test]
21 fn helpers() { assert_eq!(byte2hex(0x3A), *b"3A"); assert_eq!(int2hex(-1), *b"FF"); assert_eq!(short2hex(0x3A98), *b"3A98"); assert_eq!(num_to_hex8(0x1234), *b"1234"); }
22 #[test]
23 fn hex2bytes_writes_buffer() { let mut buf = [0u8; 16]; assert_eq!(hex2bytes("3A98FF", &mut buf), Some(3)); assert_eq!(&buf[..3], &[0x3A, 0x98, 0xFF]); assert_eq!(hex2bytes("", &mut buf), None); assert_eq!(hex2bytes("GG", &mut buf), None); }
24}