1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
pub mod buffer;
pub mod serial;
#[cfg(test)]
pub mod tests;
use std;
use std::fmt;
pub fn hexdump(
f: &mut fmt::Formatter,
prefix: &str,
buffer: &[u8],
) -> std::result::Result<(), std::fmt::Error> {
const COLUMNS: usize = 16;
let mut offset: usize = 0;
if buffer.len() == 0 {
try!(write!(f, "{}{:04x}: ", prefix, 0));
}
while offset < buffer.len() {
try!(write!(f, "{}{:04x}: ", prefix, offset));
let next_offset = offset + COLUMNS;
let (row_size, padding) = if next_offset <= buffer.len() {
(COLUMNS, 0)
} else {
(buffer.len() - offset, next_offset - buffer.len())
};
let row = &buffer[offset..offset + row_size];
for b in row {
try!(write!(f, "{:02x} ", b));
}
for _ in 0..padding {
try!(write!(f, " "));
}
for b in row {
try!(write!(
f,
"{}",
match *b {
c @ 0x20...0x7E => c as char,
_ => '.',
}
));
}
offset += COLUMNS;
if offset < buffer.len() {
try!(writeln!(f, ""));
}
}
Ok(())
}
#[allow(dead_code)]
pub struct Hex<'a>(pub &'a [u8]);
impl<'a> fmt::Display for Hex<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
hexdump(f, "", self.0)
}
}
pub fn hex(bytes: &[u8]) -> Hex {
Hex(bytes)
}
pub fn shorthash(bytes: &[u8]) -> String {
use blake2::{Blake2b, Digest};
let mut hasher = Blake2b::new();
hasher.input(bytes);
let output = hasher.result();
format!(
"{:x}{:x}{:x}{:x}",
output[0], output[1], output[2], output[3]
)
}