// Burgerservicenummer, the Dutch citizen service number. Nine digits checked
// with the eleven test: the digits weighted from nine down to one, except that
// the last is negated, must sum to a multiple of eleven. Unlike the other
// identifiers here there is no separate check digit appended to the end — the
// property holds over all nine.
///|
/// The eleven-test weights. Negating the last position is what stops a Dutch
/// bank account number, checked with the same weights all positive, from also
/// passing as a BSN.
let bsn_weights : Array[Int] = [9, 8, 7, 6, 5, 4, 3, 2, -1]
///|
/// The nine digits of a BSN, left-padded with a zero when only eight were
/// written, which is how older numbers are commonly recorded.
fn bsn_digits(s : String) -> Array[Int]? {
match digits_of(s) {
None => None
Some(d) =>
if d.length() == 9 {
Some(d)
} else if d.length() == 8 {
let out : Array[Int] = [0]
for x in d {
out.push(x)
}
Some(out)
} else {
None
}
}
}
///|
/// Validate a BSN. Both the nine-digit form and the eight-digit form with its
/// leading zero omitted are accepted. An all-zero number satisfies the
/// arithmetic but is never issued, so it is rejected.
pub fn bsn_valid(s : String) -> Bool {
match bsn_digits(s) {
None => false
Some(d) => {
let mut sum = 0
let mut all_zero = true
for i = 0; i < 9; i = i + 1 {
if d[i] != 0 {
all_zero = false
}
sum = sum + d[i] * bsn_weights[i]
}
!all_zero && sum % 11 == 0
}
}
}
///|
/// The ninth digit implied by the first eight. Returns None when the first
/// eight digits do not fix a digit, which happens when the required value would
/// have to be ten.
pub fn bsn_check_digit(first8 : String) -> Int? {
match digits_of(first8) {
None => None
Some(d) =>
if d.length() != 8 {
None
} else {
let mut sum = 0
for i = 0; i < 8; i = i + 1 {
sum = sum + d[i] * bsn_weights[i]
}
let r = sum % 11
if r == 10 {
None
} else {
Some(r)
}
}
}
}