38 lines
1.3 KiB
Text
38 lines
1.3 KiB
Text
local bigint = require "pluto:bigint"
|
|
|
|
local country_codes <const> =
|
|
"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"
|
|
|
|
local function is_valid(iban)
|
|
-- Remove spaces from IBAN.
|
|
local s = iban:replace(" ", "")
|
|
|
|
-- Check country code and length.
|
|
if not(s:sub(1, 2) .. tostring(#s)) in country_codes then
|
|
return false
|
|
end
|
|
|
|
-- Move first 4 characters to the end.
|
|
s = s:sub(5) .. s:sub(1, 4)
|
|
|
|
-- Replace A to Z with numbers 10 To 35.
|
|
for i, c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":split("") do
|
|
s = s:replace(c, tostring(i + 9))
|
|
end
|
|
|
|
-- Check whether mod 97 calculation gives a remainder of 1.
|
|
return bigint.new(s) % bigint.new(97) == bigint.new(1)
|
|
end
|
|
|
|
local ibans = { "GB82 WEST 1234 5698 7654 32", "GB82 TEST 1234 5698 7654 32" }
|
|
for ibans as iban do
|
|
local valid = is_valid(iban)
|
|
print(iban .. (valid ? " may be valid" : " is not valid"))
|
|
end
|