IBAN Validation check
JavascriptIbanJavascript Problem Overview
I need to do an IBAN validation check using JavaScript. The rules I need to follow are:
Validating the IBAN An IBAN is validated by converting it into an integer and performing a basic mod-97 operation (as described in ISO 7064) on it. If the IBAN is valid, the remainder equals 1.
-
Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
-
Move the four initial characters to the end of the string
-
Replace each letter in the string with two digits, thereby expanding the string, where A = 10, B = 11, ..., Z = 35
-
Interpret the string as a decimal integer and compute the remainder of that number on division by 97
I am doing this for a Belarusian IBAN so it has to follow the following format
2C 31N -
RU1230000000000000000000000000000
How do I modify the following to meet the above rules;
function validateIBAN(iban) {
var newIban = iban.toUpperCase(),
modulo = function(divident, divisor) {
var cDivident = '';
var cRest = '';
for (var i in divident) {
var cChar = divident[i];
var cOperator = cRest + '' + cDivident + '' + cChar;
if (cOperator < parseInt(divisor)) {
cDivident += '' + cChar;
} else {
cRest = cOperator % divisor;
if (cRest == 0) {
cRest = '';
}
cDivident = '';
}
}
cRest += '' + cDivident;
if (cRest == '') {
cRest = 0;
}
return cRest;
};
if (newIban.search(/^[A-Z]{2}/gi) < 0) {
return false;
}
newIban = newIban.substring(4) + newIban.substring(0, 4);
newIban = newIban.replace(/[A-Z]/g, function(match) {
return match.charCodeAt(0) - 55;
});
return parseInt(modulo(newIban, 97), 10) === 1;
}
console.log(validateIBAN("RU1230000000000000000000000000000"));
Javascript Solutions
Solution 1 - Javascript
Based on the work of http://toms-cafe.de/iban/iban.js I have developed my version of IBAN check.
You can modify the country support by modifying the variable CODE_LENGTHS
.
Here is my implementation:
function alertValidIBAN(iban) {
alert(isValidIBANNumber(iban));
}
/*
* Returns 1 if the IBAN is valid
* Returns FALSE if the IBAN's length is not as should be (for CY the IBAN Should be 28 chars long starting with CY )
* Returns any other number (checksum) when the IBAN is invalid (check digits do not match)
*/
function isValidIBANNumber(input) {
var CODE_LENGTHS = {
AD: 24, AE: 23, AT: 20, AZ: 28, BA: 20, BE: 16, BG: 22, BH: 22, BR: 29,
CH: 21, CR: 21, CY: 28, CZ: 24, DE: 22, DK: 18, DO: 28, EE: 20, ES: 24,
FI: 18, FO: 18, FR: 27, GB: 22, GI: 23, GL: 18, GR: 27, GT: 28, HR: 21,
HU: 28, IE: 22, IL: 23, IS: 26, IT: 27, JO: 30, KW: 30, KZ: 20, LB: 28,
LI: 21, LT: 20, LU: 20, LV: 21, 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, SE: 24, SI: 19, SK: 24, SM: 27, TN: 24, TR: 26,
AL: 28, BY: 28, CR: 22, EG: 29, GE: 22, IQ: 23, LC: 32, SC: 31, ST: 25,
SV: 28, TL: 23, UA: 29, VA: 22, VG: 24, XK: 20
};
var iban = String(input).toUpperCase().replace(/[^A-Z0-9]/g, ''), // keep only alphanumeric characters
code = iban.match(/^([A-Z]{2})(\d{2})([A-Z\d]+)$/), // match and capture (1) the country code, (2) the check digits, and (3) the rest
digits;
// check syntax and length
if (!code || iban.length !== CODE_LENGTHS[code[1]]) {
return false;
}
// rearrange country code and check digits, and convert chars to ints
digits = (code[3] + code[1] + code[2]).replace(/[A-Z]/g, function (letter) {
return letter.charCodeAt(0) - 55;
});
// final check
return mod97(digits);
}
function mod97(string) {
var checksum = string.slice(0, 2), fragment;
for (var offset = 2; offset < string.length; offset += 7) {
fragment = String(checksum) + string.substring(offset, offset + 7);
checksum = parseInt(fragment, 10) % 97;
}
return checksum;
}
input { width:300px; }
Enter IBAN
<input type="test" id="iban"/>
<button onclick="alertValidIBAN(null);">check IBAN</button>
Solution 2 - Javascript
You can use this library to validate and format an IBAN: https://github.com/arhs/iban.js (disclaimer: I wrote the library)
However, neither Russia nor Belarus are supported, as I can't find any mention of those countries on the IBAN page of wikipedia nor in the official IBAN registry so I'm afraid you'll have to modify the library code yourself to add it.
Solution 3 - Javascript
I answered a similar question. Use this list of Regular expressions to validate your IBANS. There are 70 countries, so in general you should be good to go.
AL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([a-zA-Z0-9]{4}\s?){4}\s?
AD[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([a-zA-Z0-9]{4}\s?){3}\s?
AT[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
AZ[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){5}\s?
BH[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{2})\s?
BY[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){5}\s?
BE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}\s?
BA[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
BR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{3})([a-zA-Z]{1}\s?)([a-zA-Z0-9]{1})\s?
BG[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){1}([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){1}([a-zA-Z0-9]{2})\s?
CR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
HR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{1})\s?
CY[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([a-zA-Z0-9]{4}\s?){4}\s?
CZ[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
DK[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
DO[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){5}\s?
TL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{3})\s?
EE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
FO[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
FI[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
FR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})([0-9]{2})\s?
GE[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{2})([0-9]{2}\s?)([0-9]{4}\s?){3}([0-9]{2})\s?
DE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
GI[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{3})\s?
GR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{3})\s?
GL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{2})\s?
GT[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}\s?
HU[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){6}\s?
IS[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{2})\s?
IE[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){3}([0-9]{2})\s?
IL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{3})\s?
IT[a-zA-Z0-9]{2}\s?([a-zA-Z]{1})([0-9]{3}\s?)([0-9]{4}\s?){1}([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{3})\s?
JO[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){5}([0-9]{2})\s?
KZ[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{2})\s?
XK[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{4}\s?){2}([0-9]{2})([0-9]{2}\s?)\s?
KW[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}([a-zA-Z0-9]{2})\s?
LV[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{1})\s?
LB[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}\s?
LI[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})\s?
LT[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}\s?
LU[a-zA-Z0-9]{2}\s?([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){3}\s?
MK[a-zA-Z0-9]{2}\s?([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})([0-9]{2})\s?
MT[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{3})\s?
MR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{3})\s?
MU[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){4}([0-9]{3})([a-zA-Z]{1}\s?)([a-zA-Z]{2})\s?
MC[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})([0-9]{2})\s?
MD[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){4}\s?
ME[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
NL[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){2}([0-9]{2})\s?
NO[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){2}([0-9]{3})\s?
PK[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){4}\s?
PS[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){5}([0-9]{1})\s?
PL[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){6}\s?
PT[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}([0-9]{1})\s?
QA[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){5}([a-zA-Z0-9]{1})\s?
RO[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([a-zA-Z0-9]{4}\s?){4}\s?
SM[a-zA-Z0-9]{2}\s?([a-zA-Z]{1})([0-9]{3}\s?)([0-9]{4}\s?){1}([0-9]{3})([a-zA-Z0-9]{1}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{3})\s?
SA[a-zA-Z0-9]{2}\s?([0-9]{2})([a-zA-Z0-9]{2}\s?)([a-zA-Z0-9]{4}\s?){4}\s?
RS[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){4}([0-9]{2})\s?
SK[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
SI[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){3}([0-9]{3})\s?
ES[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
SE[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
CH[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){2}([a-zA-Z0-9]{1})\s?
TN[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){5}\s?
TR[a-zA-Z0-9]{2}\s?([0-9]{4}\s?){1}([0-9]{1})([a-zA-Z0-9]{3}\s?)([a-zA-Z0-9]{4}\s?){3}([a-zA-Z0-9]{2})\s?
AE[a-zA-Z0-9]{2}\s?([0-9]{3})([0-9]{1}\s?)([0-9]{4}\s?){3}([0-9]{3})\s?
GB[a-zA-Z0-9]{2}\s?([a-zA-Z]{4}\s?){1}([0-9]{4}\s?){3}([0-9]{2})\s?
VA[a-zA-Z0-9]{2}\s?([0-9]{3})([0-9]{1}\s?)([0-9]{4}\s?){3}([0-9]{2})\s?
VG[a-zA-Z0-9]{2}\s?([a-zA-Z0-9]{4}\s?){1}([0-9]{4}\s?){4}\s?
Solution 4 - Javascript
"Jquery validation plugin" also supports iban check:
https://github.com/jzaefferer/jquery-validation/blob/master/src/additional/iban.js
Solution 5 - Javascript
Based on previous answers I created a Directive
that implements Angular Validator
method.
I also added the types.
iban-validator.directive.ts
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { Directive } from '@angular/core';
@Directive({
selector: '[ibanValidators]',
providers: [{
provide: NG_VALIDATORS,
useExisting: IbanValidatorDirective,
multi: true
}]
})
export class IbanValidatorDirective implements Validator {
validate(control: AbstractControl): object {
const codeLengths = {
AD: 24, AE: 23, AL: 28, AT: 20, AZ: 28, BA: 20, BE: 16, BG: 22, BH: 22, BR: 29, CH: 21, CR: 21, CY: 28, CZ: 24,
DE: 22, DK: 18, DO: 28, EE: 20, ES: 24, LC: 30, FI: 18, FO: 18, FR: 27, GB: 22, GI: 23, GL: 18, GR: 27, GT: 28,
HR: 21, HU: 28, IE: 22, IL: 23, IS: 26, IT: 27, JO: 30, KW: 30, KZ: 20, LB: 28, LI: 21, LT: 20, LU: 20, LV: 21,
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, SE: 24, SI: 19, SK: 24, SM: 27, TN: 24, TR: 26
};
if (control.value) {
const iban = control.value.toUpperCase().replace(/[^A-Z0-9]/g, '');
const code = iban.match(/^([A-Z]{2})(\d{2})([A-Z\d]+)$/);
let digits: number;
if (!code || iban.length !== codeLengths[code[1]]) {
return { ibanValid: false };
}
digits = (code[3] + code[1] + code[2]).replace(/[A-Z]/g, (letter: string) => {
return letter.charCodeAt(0) - 55;
});
return this.mod97(digits) === 1 ? null : { ibanValid: false };
}
}
private mod97(digital: number | string) {
digital = digital.toString();
let checksum: number | string = digital.slice(0, 2);
let fragment = '';
for (let offset = 2; offset < digital.length; offset += 7) {
fragment = checksum + digital.substring(offset, offset + 7);
checksum = parseInt(fragment, 10) % 97;
}
return checksum;
}
}
Then just use the directive on an input.
Solution 6 - Javascript
I know this is an old topic, but since it showed up on #1 place on Google, and since the solutions here aren't really refined I would like to show you my take on it:
export const validIban = (value) => {
let rearrange =
value.substring(4, value.length)
+ value.substring(0, 4);
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
let alphaMap = {};
let number = [];
alphabet.forEach((value, index) => {
alphaMap[value] = index + 10;
});
rearrange.split('').forEach((value, index) => {
number[index] = alphaMap[value] || value;
});
return modulo(number.join('').toString(), 97) === 1;
}
const modulo = (aNumStr, aDiv) => {
var tmp = "";
var i, r;
for (i = 0; i < aNumStr.length; i++) {
tmp += aNumStr.charAt(i);
r = tmp % aDiv;
tmp = r.toString();
}
return tmp / 1;
}
It works pretty well for me you can test it with
validIban(testThis)
/ http://randomiban.com
Solution 7 - Javascript
Based on the last SWIFT IBAN Registrar publication (June 2021), available here, I updated Rony Nasr's REGEX proposal. It includes 79 countries and checks country-specific IBAN structure and length. (It does NOT, however, do a checksum MOD97 verification).
/^(?:(?:CR|DE|ME|RS|VA)\d{20}|(?:CZ|ES|SE|SK|TN)\d{22}|(?:DK|FI|FO|GL|SD)\d{16}|(?:AT|BA|EE|LT|XK)\d{18}|(?:AE|IL|TL)\d{21}|(?:LY|PT|ST)\d{23}|(?:IT|SM)\d{2}[A-Z]\d{10}[A-Za-z0-9]{12}|(?:HU|PL)\d{26}|(?:AL|CY)\d{10}[A-Za-z0-9]{16}|(?:CH|LI)\d{7}[A-Za-z0-9]{12}|(?:FR|MC)\d{12}[A-Za-z0-9]{11}\d{2}|(?:GB|IE)\d{2}[A-Z]{4}\d{14}|(?:KZ|LU)\d{5}[A-Za-z0-9]{13}|(?:GI|IQ)\d{2}[A-Z]{4}[A-Za-z0-9]{15}|(?:PK|RO)\d{2}[A-Z]{4}[A-Za-z0-9]{16}|(?:PS|QA)\d{2}[A-Z]{4}[A-Za-z0-9]{21}|AD\d{10}[A-Za-z0-9]{12}|AZ\d{2}[A-Z]{4}[A-Za-z0-9]{20}|BE\d{14}|BG\d{2}[A-Z]{4}\d{6}[A-Za-z0-9]{8}|BH\d{2}[A-Z]{4}[A-Za-z0-9]{14}|BR\d{25}[A-Z][A-Za-z0-9]|BY\d{2}[A-Za-z0-9]{4}\d{4}[A-Za-z0-9]{16}|DO\d{2}[A-Za-z0-9]{4}\d{20}|EG\d{27}|GE\d{2}[A-Z]\d{16}|GT\d{2}[A-Za-z0-9]{24}|GR\d{9}[A-Za-z0-9]{16}|HR\d{19}|IS\d{24}|JO\d{2}[A-Z]{4}\d{4}[A-Za-z0-9]{18}|KW\d{2}[A-Z]{4}[A-Za-z0-9]{22}|LC\d{2}[A-Z]{4}[A-Za-z0-9]{24}|LB\d{6}[A-Za-z0-9]{20}|LV\d{2}[A-Z]{4}\d{13}|MD\d{2}[A-Za-z0-9]{20}|MK\d{5}[A-Za-z0-9]{10}\d{2}|MR\d{25}|MT\d{2}[A-Z]{4}\d{5}[A-Za-z0-9]{18}|MU\d{2}[A-Z]{4}\d{19}[A-Z]{3}|NL\d{2}[A-Z]{4}\d{10}|NO\d{13}|SA\d{4}[A-Za-z0-9]{18}|SC\d{2}[A-Z]{4}\d{20}[A-Z]{3}|SI\d{17}|SV\d{2}[A-Z]{4}\d{20}|TR\d{8}[A-Za-z0-9]{16}|UA\d{8}[A-Za-z0-9]{19}|VG\d{2}[A-Z]{4}\d{16}|GE\d{2}[A-Z]{2}\d{16})$/gm
Solution 8 - Javascript
I wrote 2 regexes, the first one is for SEPA-only countries, the other is for all countries that support IBAN, as of 2021-10.
IBAN regex for within-SEPA area countries
The first one checks if an IBAN is valid within the SEPA area, the IBAN must belong to a country that is within the SEPA area. (it considers IBAN outside the SEPA area as invalid)
^(?:((?:IT|SM)\d{2}[A-Z]{1}\d{22})|(NL\d{2}[A-Z]{4}\d{10})|(LV\d{2}[A-Z]{4}\d{13})|((?:BG|GB|IE)\d{2}[A-Z]{4}\d{14})|(GI\d{2}[A-Z]{4}\d{15})|(RO\d{2}[A-Z]{4}\d{16})|(MT\d{2}[A-Z]{4}\d{23})|(NO\d{13})|((?:DK|FI)\d{16})|((?:SI)\d{17})|((?:AT|EE|LU|LT)\d{18})|((?:HR|LI|CH)\d{19})|((?:DE|VA)\d{20})|((?:AD|CZ|ES|MD|SK|SE)\d{22})|(PT\d{23})|((?:IS)\d{24})|((?:BE)\d{14})|((?:FR|MC|GR)\d{25})|((?:PL|HU|CY)\d{26}))$
Specifications:
- https://www.iban.com/structure
- https://docs.google.com/spreadsheets/d/1376mu58jQ2P5jGX7tIXGrFfwgfo0RHO7RBRSpKcViIs/edit?usp=sharing Google Sheet based on the above data structure, easier to work with
Testing: https://regex101.com/r/oLRltj/1/
IBAN regex for any country
^(?:(?:CR|DE|ME|RS|VA)\d{20}|(?:CZ|ES|SE|SK|TN)\d{22}|(?:DK|FI|FO|GL|SD)\d{16}|(?:AT|BA|EE|LT|XK)\d{18}|(?:AE|IL|TL)\d{21}|(?:LY|PT|ST)\d{23}|(?:IT|SM)\d{2}[A-Z]\d{10}[A-Za-z0-9]{12}|(?:HU|PL)\d{26}|(?:AL|CY)\d{10}[A-Za-z0-9]{16}|(?:CH|LI)\d{7}[A-Za-z0-9]{12}|(?:FR|MC)\d{12}[A-Za-z0-9]{11}\d{2}|(?:GB|IE)\d{2}[A-Z]{4}\d{14}|(?:KZ|LU)\d{5}[A-Za-z0-9]{13}|(?:GI|IQ)\d{2}[A-Z]{4}[A-Za-z0-9]{15}|(?:PK|RO)\d{2}[A-Z]{4}[A-Za-z0-9]{16}|(?:PS|QA)\d{2}[A-Z]{4}[A-Za-z0-9]{21}|AD\d{10}[A-Za-z0-9]{12}|AZ\d{2}[A-Z]{4}[A-Za-z0-9]{20}|BE\d{14}|BG\d{2}[A-Z]{4}\d{6}[A-Za-z0-9]{8}|BH\d{2}[A-Z]{4}[A-Za-z0-9]{14}|BR\d{25}[A-Z][A-Za-z0-9]|BY\d{2}[A-Za-z0-9]{4}\d{4}[A-Za-z0-9]{16}|DO\d{2}[A-Za-z0-9]{4}\d{20}|EG\d{27}|GE\d{2}[A-Z]\d{16}|GT\d{2}[A-Za-z0-9]{24}|GR\d{9}[A-Za-z0-9]{16}|HR\d{19}|IS\d{24}|JO\d{2}[A-Z]{4}\d{4}[A-Za-z0-9]{18}|KW\d{2}[A-Z]{4}[A-Za-z0-9]{22}|LC\d{2}[A-Z]{4}[A-Za-z0-9]{24}|LB\d{6}[A-Za-z0-9]{20}|LV\d{2}[A-Z]{4}\d{13}|MD\d{2}[A-Za-z0-9]{20}|MK\d{5}[A-Za-z0-9]{10}\d{2}|MR\d{25}|MT\d{2}[A-Z]{4}\d{5}[A-Za-z0-9]{18}|MU\d{2}[A-Z]{4}\d{19}[A-Z]{3}|NL\d{2}[A-Z]{4}\d{10}|NO\d{13}|SA\d{4}[A-Za-z0-9]{18}|SC\d{2}[A-Z]{4}\d{20}[A-Z]{3}|SI\d{17}|SV\d{2}[A-Z]{4}\d{20}|TR\d{8}[A-Za-z0-9]{16}|UA\d{8}[A-Za-z0-9]{19}|VG\d{2}[A-Z]{4}\d{16}|GE\d{2}[A-Z]{2}\d{16})$
This second regex was taken from https://stackoverflow.com/a/69068004/2391795, and slightly modified to add proper support for GE (Georgia) country.
Testing: https://regex101.com/r/I3oiuo/1/
Solution 9 - Javascript
> Just using this website api : go to https://api.ibanapi.com and get > apk_key > > iban = SA4705000068203056854000 > api_key = ea649b36c1d1648bf0f12df82a8da475e2ee3447 > url = 'https://api.ibanapi.com/v1/validate/'iban+'?api_key='+api_key+''; > > The IBAN Checker > > - Check the structure of the IBAN and prepare it for the validation engine > - Make sure the country supports the IBAN as per the Swift public registery > - Validate the IBAN using the check digits. > - If the country level validation is supported, it will run through it > - Get the bank information for this IBAN from our registery
Solution 10 - Javascript
I have managed to create the below RegEx for quick validation based on the current format.
/^(?:(?:IT|SM)\d{2}[A-Z]\d{22}|NL\d{2}[A-Z]{4}\d{10}|RO\d{2}[A-Z]{4}\d[A-Z]\d{14}|LV\d{2}[A-Z]{4}\d{13}|FR\d{19}[A-Z]\d{5}|LI\d{17}[A-Z]{2}|MD\d{2}[A-Z]{2}\d{18}|(?:BG|GB|IE)\d{2}[A-Z]{4}\d{14}|BH\d{2}[A-Z]{4}\d{10}[A-Z]{2}\d{2}|GE\d{2}[A-Z]{2}\d{16}|GI\d{2}[A-Z]{4}\d{15}|BR\d{25}[A-Z]\d|MU\d{2}[A-Z]{4}\d{19}[A-Z]{3}|PS\d{2}[A-Z]{4}\d{21}|QA\d{2}[A-Z]{4}\d{14}[A-Z]{7}|(?:AZ|DO|GT)\d{2}[A-Z]{4}\d{20}|(?:BJ|ML|SN|CI)\d{2}[A-Z]\d{23}|(?:PK|VG)\d{2}[A-Z]{4}\d{16}|(?:KW|JO)\d{2}[A-Z]{4}\d{22}|MT\d{2}[A-Z]{4}\d{12}[A-Z]{7}\d{3}[A-Z]|NO\d{13}|(?:BE|BI)\d{14}|(?:DK|FI|GL|FO)\d{16}|(?:MK|SI)\d{17}|(?:BA|LT|AT|EE|KZ|LU|XK)\d{18}|(?:HR|CH|CR)\d{19}|(?:DE|ME|RS)\d{20}|(?:AE|IL|TL)\d{21}|(?:AD|CZ|ES|SA|DZ|SK|SE|TN)\d{22}|(?:PT|AO|CV|MZ)\d{23}|(?:IS|IR|TR)\d{24}|(?:MR|MC|BF|CM|GR|MG)\d{25}|(?:AL|DO|LB|PL|CY|HU)\d{26})$/i