JSFiddle - React, Tailwind, and code Playground
by Plippie Plop
JavaScript
const countryLengths = {
AD: 24, AE: 23, AL: 28, AT: 20, AZ: 28, BA: 20, BE: 16, BG: 22, BH: 22, BI: 28, BR: 29, BY: 28,
CH: 21, CR: 22, CY: 28, CZ: 24, DE: 22, DK: 18, DO: 28, EE: 20, EG: 29, ES: 24, LC: 32, FI: 18,
FO: 18, FR: 27, GB: 22, GE: 22, GI: 23, GL: 18, GR: 27, GT: 28, HR: 21, HU: 28, IE: 22, IL: 23,
IQ: 23, IS: 26, IT: 27, JO: 30, KW: 30, KZ: 20, LB: 28, LI: 21, LT: 20, LU: 20, LV: 21, LY: 25,
MC: 27, MD: 24, ME: 22, MK: 19, MR: 27, MT: 31, MU: 30, NL: 18, NO: 15, PK: 24, PL: 28, PS: 29,
PT: 25, QA: 29, RO: 24, RS: 22, SA: 24, SC: 31, SD: 18, SE: 24, SI: 19, SK: 24, SM: 27, ST: 25,
SV: 28, TL: 23, TN: 24, TR: 26, UA: 29, VA: 22, VG: 24, XK: 20
};
function isValid(input) {
if (typeof input !== 'string') {
return false;
}
const iban = input.toUpperCase();
const countryCode = iban.slice(0, 2);
if (!Object.keys(countryLengths).includes(countryCode)) {
return false;
}
if (countryLengths[countryCode] !== iban.length) {
return false;
}
const ibanMovedInitials = `${iban.slice(4)}${iban.slice(0, 4)}`;
const lettersRegex = /[A-Z]/g;
const onlyDigits = ibanMovedInitials.replace(lettersRegex, (match) =>
letterToTwoDigits(match)
);
return mod97(onlyDigits) === 1;
}
function mod97(numStr) {
if (typeof numStr !== 'string') {
throw new Error('`numStr` parameter must be a string.');
}
let checksum = numStr.slice(0, 2);
let fragment = '';
for (let offset = 2; offset < numStr.length; offset += 7) {
fragment = checksum + numStr.substring(offset, offset + 7);
checksum = parseInt(fragment, 10) % 97;
}
return checksum;
}
function letterToTwoDigits(letter) {
if (typeof letter !== 'string') {
throw new Error('`letter` parameter must be a string.');
}
return letter.charCodeAt(0) - 55;
}