|
| 1 | +/// Converts a single hex character to its integer value. |
| 2 | +/// Returns None if the character is not valid (0-9, a-f, or A-F). |
| 3 | +fn hex_char_to_val(c: char) -> Option<i32> { |
| 4 | + match c { |
| 5 | + '0'..='9' => Some(c as i32 - '0' as i32), |
| 6 | + 'a'..='f' => Some(c as i32 - 'a' as i32 + 10), |
| 7 | + 'A'..='F' => Some(c as i32 - 'A' as i32 + 10), |
| 8 | + _ => None, |
| 9 | + } |
| 10 | +} |
| 11 | + |
| 12 | +/// Converts two hex characters into a combined integer value. |
| 13 | +/// Returns None if either character is invalid. |
| 14 | +pub fn hex_to_int(high: char, low: char) -> Option<i32> { |
| 15 | + let h = hex_char_to_val(high)?; |
| 16 | + let l = hex_char_to_val(low)?; |
| 17 | + Some(h * 16 + l) |
| 18 | +} |
| 19 | + |
| 20 | +pub fn hex_string_to_int(string: &str, len: usize) -> Option<i32> { |
| 21 | + let mut result = 0; |
| 22 | + for c in string.chars().take(len) { |
| 23 | + result = result * 16 + hex_char_to_val(c)?; |
| 24 | + } |
| 25 | + Some(result) |
| 26 | +} |
| 27 | + |
| 28 | +#[cfg(test)] |
| 29 | +mod tests { |
| 30 | + use super::*; |
| 31 | + |
| 32 | + #[test] |
| 33 | + fn test_hex_to_int() { |
| 34 | + assert_eq!(hex_to_int('4', 'f'), Some(79)); |
| 35 | + assert_eq!(hex_to_int('0', '0'), Some(0)); |
| 36 | + assert_eq!(hex_to_int('f', 'f'), Some(255)); |
| 37 | + assert_eq!(hex_to_int('A', 'F'), Some(175)); |
| 38 | + assert_eq!(hex_to_int('z', '1'), None); |
| 39 | + } |
| 40 | + |
| 41 | + #[test] |
| 42 | + fn test_hex_string_to_int() { |
| 43 | + assert_eq!(hex_string_to_int("4f", 2), Some(79)); |
| 44 | + assert_eq!(hex_string_to_int("ff", 2), Some(255)); |
| 45 | + assert_eq!(hex_string_to_int("00", 2), Some(0)); |
| 46 | + assert_eq!(hex_string_to_int("ffff", 4), Some(65535)); |
| 47 | + assert_eq!(hex_string_to_int("4f", 1), Some(4)); |
| 48 | + assert_eq!(hex_string_to_int("FF", 2), Some(255)); |
| 49 | + assert_eq!(hex_string_to_int("zz", 2), None); |
| 50 | + } |
| 51 | +} |
0 commit comments