Family Day update

This commit is contained in:
Ingy döt Net 2020-02-17 23:21:07 -08:00
parent aac6731f2c
commit 9ad63ea473
2442 changed files with 39761 additions and 8255 deletions

View file

@ -2,39 +2,43 @@
import java.math.BigInteger
object Iban {
object IBAN {
/* List updated to release 73, January 2017, of IBAN Registry (75 countries) */
private val countryCodes =
"AD24 AE23 AL28 AT20 AZ28 BA20 BE16 BG22 BH22 BR29 BY28 CH21 CR22 CY28 CZ24 DE22 " +
"DK18 DO28 EE20 ES24 FI18 FO18 FR27 GB22 GE22 GI23 GL18 GR27 GT28 HR21 HU28 IE22 " +
"IL23 IQ23 IS26 IT27 JO30 KW30 KZ20 LB28 LC32 LI21 LT20 LU20 LV21 MC27 MD24 ME22 " +
"MK19 MR27 MT31 MU30 NL18 NO15 PK24 PL28 PS29 PT25 QA29 RO24 RS22 SA24 SC31 SE24 " +
"SI19 SK24 SM27 ST25 SV28 TL23 TN24 TR26 UA29 VG24 XK20"
private const val countryCodes = "" +
"AD24 AE23 AL28 AT20 AZ28 BA20 BE16 BG22 BH22 BR29 " +
"BY28 CH21 CR22 CY28 CZ24 DE22 DK18 DO28 EE20 ES24 " +
"FI18 FO18 FR27 GB22 GE22 GI23 GL18 GR27 GT28 HR21 " +
"HU28 IE22 IL23 IQ23 IS26 IT27 JO30 KW30 KZ20 LB28 " +
"LC32 LI21 LT20 LU20 LV21 MC27 MD24 ME22 MK19 MR27 " +
"MT31 MU30 NL18 NO15 PK24 PL28 PS29 PT25 QA29 RO24 " +
"RS22 SA24 SC31 SE24 SI19 SK24 SM27 ST25 SV28 TL23 " +
"TN24 TR26 UA29 VG24 XK20"
private fun checkCountryCode(cc: String) = cc in countryCodes
fun validate(iban: String): Boolean {
fun isValid(iban: String): Boolean {
// remove spaces from IBAN
var s = iban.replace(" ", "")
// check country code
if (!checkCountryCode(s.substring(0, 2) + s.length)) return false
// check country code and length
s.substring(0, 2) + s.length in countryCodes || return false
// move first 4 characters to end
// move first 4 characters to the end
s = s.substring(4) + s.substring(0, 4)
// replace A to Z with numbers 10 To 35
for (ch in 'A'..'Z') s = s.replace(ch.toString(), (ch - 55).toInt().toString())
s = s.replace(Regex("[A-Z]")) { (10 + (it.value[0] - 'A')).toString() }
// check whether mod 97 calculation gives a remainder of 1
return BigInteger(s) % BigInteger.valueOf(97L) == BigInteger.ONE
}
}
fun main(args: Array<String>) {
val ibans = arrayOf("GB82 WEST 1234 5698 7654 32", "GB82 TEST 1234 5698 7654 32")
fun main() {
val ibans = arrayOf(
"GB82 WEST 1234 5698 7654 32",
"GB82 TEST 1234 5698 7654 32"
)
for (iban in ibans) {
val isValid = Iban.validate(iban)
println(iban + if(isValid) " may be valid" else " is not valid")
val valid = IBAN.isValid(iban)
println(iban + if (valid) " may be valid" else " is not valid")
}
}

View file

@ -0,0 +1,59 @@
let cc = ["AD","AE","AL","AO","AT","AZ","BA","BE","BF","BG","BH","BI","BJ","BR","CG","CH","CI","CM","CR","CV","CY",
"CZ","DE","DK","DO","DZ","EE","EG","ES","FI","FO","FR","GA","GB","GE","GI","GL","GR","GT","HR","HU","IE",
"IL","IR","IS","IT","JO","KW","KZ","LB","LI","LT","LU","LV","MC","MD","ME","MG","MK","ML","MR","MT","MU",
"MZ","NL","NO","PK","PL","PS","PT","QA","RO","RS","SA","SE","SI","SK","SM","SN","TN","TR","UA","VG"]
let ln = [ 24, 23, 28, 25, 20, 28, 20, 16, 27, 22, 22, 16, 28, 29, 27, 21, 28, 27, 21, 25, 28,
24, 22, 18, 28, 24, 20, 27, 24, 18, 18, 27, 27, 22, 22, 23, 18, 27, 28, 21, 28, 22,
23, 26, 26, 27, 30, 30, 20, 28, 21, 20, 20, 21, 27, 24, 22, 27, 19, 28, 27, 31, 30,
25, 18, 15, 24, 28, 29, 25, 29, 24, 22, 24, 24, 19, 24, 27, 28, 24, 26, 29, 24 ]
def ccToLen(s: string) -> int:
let cnt, idx = binary_search(cc, s.substring(0, 2))
if cnt == 1:
return ln[idx]
else:
return -1
def strip(s: string) -> string:
let t = s.tokenize(" ", " ") // splits on spaces and trims spaces from segments
return t.concat_string("") // joins it back together
def rotmod97step(accumu: int, c: int) -> int:
accumu *= 10
if '0' <= c and c <= '9':
accumu += c - '0'
else: if 'A' <= c and c <= 'Z':
accumu *= 10
accumu += c + 10 - 'A'
else:
return -1
while accumu >= 97:
accumu -= 97
return accumu
def rotmod97(s: string) -> int:
// the first four chars come last
// all chars from 'A' to 'Z' => "10" to "35"
let len = s.length
var accumu = 0 // result; negative indicates error
var i = 4 // starting index
while i < len and accumu >= 0:
accumu = rotmod97step(accumu, s[i])
i += 1
i = 0
while i < 4 and accumu >= 0:
accumu = rotmod97step(accumu, s[i])
i += 1
return accumu
def isValidIBAN(iban: string) -> bool:
let s = strip(uppercase(iban))
if s.length == ccToLen(s):
return rotmod97(s) == 1
else:
return false
assert isValidIBAN("GB82 WEST 1234 5698 7654 32")
assert isValidIBAN("GB82 West 1234 5698 7654 32")
assert not isValidIBAN("GB82 TEST 1234 5698 7654 32")
assert not isValidIBAN("GB82 WEST 1243 5698 7654 32")