66 lines
2.3 KiB
Rust
66 lines
2.3 KiB
Rust
fn main() {
|
|
for iban in [
|
|
"",
|
|
"x",
|
|
"QQ82",
|
|
"QQ82W",
|
|
"GB82 TEST 1234 5698 7654 322",
|
|
"gb82 WEST 1234 5698 7654 32",
|
|
"GB82 WEST 1234 5698 7654 32",
|
|
"GB82 TEST 1234 5698 7654 32",
|
|
"GB81 WEST 1234 5698 7654 32",
|
|
"SA03 8000 0000 6080 1016 7519",
|
|
"CH93 0076 2011 6238 5295 7",
|
|
].iter()
|
|
{
|
|
println!(
|
|
"'{}' is {}valid",
|
|
iban,
|
|
if validate_iban(iban) { "" } else { "NOT " }
|
|
);
|
|
}
|
|
}
|
|
|
|
fn validate_iban(iban: &str) -> bool {
|
|
let iso_len = [
|
|
("AL", 28), ("AD", 24), ("AT", 20), ("AZ", 28), ("BE", 16), ("BH", 22),
|
|
("BA", 20), ("BR", 29), ("BG", 22), ("HR", 21), ("CY", 28), ("CZ", 24),
|
|
("DK", 18), ("DO", 28), ("EE", 20), ("FO", 18), ("FI", 18), ("FR", 27),
|
|
("GE", 22), ("DE", 22), ("GI", 23), ("GL", 18), ("GT", 28), ("HU", 28),
|
|
("IS", 26), ("IE", 22), ("IL", 23), ("IT", 27), ("KZ", 20), ("KW", 30),
|
|
("LV", 21), ("LB", 28), ("LI", 21), ("LT", 20), ("LU", 20), ("MK", 19),
|
|
("MT", 31), ("MR", 27), ("MU", 30), ("MC", 27), ("MD", 24), ("ME", 22),
|
|
("NL", 18), ("NO", 15), ("PK", 24), ("PS", 29), ("PL", 28), ("PT", 25),
|
|
("RO", 24), ("SM", 27), ("SA", 24), ("RS", 22), ("SK", 24), ("SI", 19),
|
|
("ES", 24), ("SE", 24), ("CH", 21), ("TN", 24), ("TR", 26), ("AE", 23),
|
|
("GB", 22), ("VG", 24), ("GR", 27), ("CR", 21),
|
|
];
|
|
let trimmed_iban = iban.chars()
|
|
.filter(|&ch| ch != ' ')
|
|
.collect::<String>()
|
|
.to_uppercase();
|
|
if trimmed_iban.len() < 4 {
|
|
return false;
|
|
}
|
|
let prefix = &trimmed_iban[0..2];
|
|
if let Some(pair) = iso_len.iter().find(|&&(code, _)| code == prefix) {
|
|
if pair.1 != trimmed_iban.len() {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
let reversed_iban = format!("{}{}", &trimmed_iban[4..], &trimmed_iban[0..4]);
|
|
let mut expanded_iban = String::new();
|
|
for ch in reversed_iban.chars() {
|
|
expanded_iban.push_str(&if ch.is_numeric() {
|
|
format!("{}", ch)
|
|
} else {
|
|
format!("{}", ch as u8 - 'A' as u8 + 10u8)
|
|
});
|
|
}
|
|
expanded_iban.bytes().fold(0, |acc, ch| {
|
|
(acc * 10 + ch as u32 - '0' as u32) % 97
|
|
}) == 1
|
|
}
|