1pub fn hex_encode(bytes: &[u8]) -> String {
2 let mut out = String::with_capacity(bytes.len() * 2);
3 for b in bytes {
4 out.push_str(&format!("{b:02x}"));
5 }
6 out
7}
8
9pub fn hex_decode(input: &str) -> Result<Vec<u8>, String> {
10 let input = input.trim();
11 if !input.len().is_multiple_of(2) {
12 return Err("hex string must have even length".to_string());
13 }
14
15 let mut out = Vec::with_capacity(input.len() / 2);
16 let bytes = input.as_bytes();
17 for i in (0..bytes.len()).step_by(2) {
18 let hi = (bytes[i] as char).to_digit(16);
19 let lo = (bytes[i + 1] as char).to_digit(16);
20 let Some(hi) = hi else {
21 return Err(format!("invalid hex character: {}", bytes[i] as char));
22 };
23 let Some(lo) = lo else {
24 return Err(format!("invalid hex character: {}", bytes[i + 1] as char));
25 };
26 out.push(((hi << 4) | lo) as u8);
27 }
28 Ok(out)
29}