rosetta/validate_international_securities_identification_number.bruijn

Problem description

:import luhn_test_of_credit_card_numbers .

:import std/Number/Conversion .
:import std/Combinator .
:import std/String .
:import std/Char .
:import std/Logic .
:import std/Number .

# verifies ISIN format
format? [len ⋀? country ⋀? security ⋀? checksum]
	len (length 0) =? (+12)
	country all? uppercase? (take (+2) 0)
	security all? (φ or? uppercase? numeric?) (take (+9) (drop (+2) 0))
	checksum numeric? _0

# performs luhn test
checksum? (map (from-base36 → number→string)) → concat → string→number → luhn
	from-base36 binary→ternary → [(0 - (0 ≥? (+65) ((+65) - (+10)) (+48)))]

# performs format and checksum test
validate φ and? format? checksum?

:test (validate "US0378331005") (true)
:test (validate "US0373831005") (false)
:test (validate "U50378331005") (false)
:test (validate "US03378331005") (false)
:test (validate "AU0000XVGZA3") (true)
:test (validate "AU0000VXGZA3") (true)
:test (validate "FR0000988040") (true)