local bigint = require "pluto:bigint" local country_codes = "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