RosettaCodeData/Task/IBAN/Pluto/iban.pluto
2026-04-30 12:34:36 -04:00

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