]> git.proxmox.com Git - proxmox-backup.git/blob - proxmox-protocol/src/tools.rs
a614e28ff4037f8e44a5b268b78e5266116d8011
[proxmox-backup.git] / proxmox-protocol / src / tools.rs
1 use failure::{bail, Error};
2
3 pub fn digest_to_hex(digest: &[u8]) -> String {
4 const HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef";
5
6 let mut buf = Vec::<u8>::with_capacity(digest.len() * 2);
7
8 for i in 0..digest.len() {
9 buf.push(HEX_CHARS[(digest[i] >> 4) as usize]);
10 buf.push(HEX_CHARS[(digest[i] & 0xf) as usize]);
11 }
12
13 unsafe { String::from_utf8_unchecked(buf) }
14 }
15
16 pub unsafe fn swapped_data_to_buf<T>(data: &T) -> &[u8] {
17 std::slice::from_raw_parts(data as *const T as *const u8, std::mem::size_of::<T>())
18 }
19
20 fn hex_nibble(c: u8) -> Result<u8, Error> {
21 Ok(match c {
22 b'0'..=b'9' => c - b'0',
23 b'a'..=b'f' => c - b'a' + 0xa,
24 b'A'..=b'F' => c - b'A' + 0xa,
25 _ => bail!("not a hex digit: {}", c as char),
26 })
27 }
28
29 #[inline]
30 pub fn parse_hex_digest<T: AsRef<[u8]>>(hex: T) -> Result<[u8; 32], Error> {
31 let mut digest: [u8; 32] = unsafe { std::mem::uninitialized() };
32
33 let hex = hex.as_ref();
34
35 if hex.len() != 64 {
36 bail!(
37 "invalid hex digest ({} instead of 64 digits long)",
38 hex.len()
39 );
40 }
41
42 for i in 0..32 {
43 digest[i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
44 }
45
46 Ok(digest)
47 }