Family Day update
This commit is contained in:
parent
aac6731f2c
commit
9ad63ea473
2442 changed files with 39761 additions and 8255 deletions
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
Task/IBAN/Lobster/iban.lobster
Normal file
59
Task/IBAN/Lobster/iban.lobster
Normal 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")
|
||||
Loading…
Add table
Add a link
Reference in a new issue