const WEIGHTS: [usize; 3] = [7, 3, 1];
pub fn get_check_digit(input: &str) -> u8 {
let sum: usize = input
.chars()
.enumerate()
.map(|(i, c)| {
let value = if c.is_ascii_uppercase() {
(c as usize - 'A' as usize) + 10
} else if c.is_ascii_digit() {
c as usize - '0' as usize
} else {
0
};
value * WEIGHTS[i % WEIGHTS.len()]
})
.sum();
(sum % 10) as u8
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_letters_and_digits() {
assert_eq!(get_check_digit("L898902C3"), 6);
assert_eq!(get_check_digit("0"), 0);
assert_eq!(get_check_digit("1"), 7);
assert_eq!(get_check_digit("9"), 3);
assert_eq!(get_check_digit("A"), 0);
assert_eq!(get_check_digit("MRZ12"), 3);
}
#[test]
fn test_non_mrz_chars_treated_as_zero() {
assert_eq!(get_check_digit("<"), 0);
assert_eq!(get_check_digit("ABC<123"), {
1
});
}
#[test]
fn test_long_input() {
let s = "L898902C360X"; let d = get_check_digit(s);
assert!(d <= 9);
}
}