2 * IBAN is the international bank account number.
3 * It has a country - specific format, that is checked here too
5 $.validator
.addMethod("iban", function(value
, element
) {
6 // some quick simple tests to prevent needless work
7 if (this.optional(element
)) {
11 // remove spaces and to upper case
12 var iban
= value
.replace(/ /g
, "").toUpperCase(),
17 countrycode
, ibancheck
, charAt
, cChar
, bbanpattern
, bbancountrypatterns
, ibanregexp
, i
, p
;
19 if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(iban
))) {
23 // check the country code and find the country specific format
24 countrycode
= iban
.substring(0, 2);
25 bbancountrypatterns
= {
26 "AL": "\\d{8}[\\dA-Z]{16}",
27 "AD": "\\d{8}[\\dA-Z]{12}",
29 "AZ": "[\\dA-Z]{4}\\d{20}",
31 "BH": "[A-Z]{4}[\\dA-Z]{14}",
33 "BR": "\\d{23}[A-Z][\\dA-Z]",
34 "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
37 "CY": "\\d{8}[\\dA-Z]{16}",
40 "DO": "[A-Z]{4}\\d{20}",
44 "FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
45 "GE": "[\\dA-Z]{2}\\d{16}",
47 "GI": "[A-Z]{4}[\\dA-Z]{15}",
48 "GR": "\\d{7}[\\dA-Z]{16}",
50 "GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
53 "IE": "[\\dA-Z]{4}\\d{14}",
55 "IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
56 "KZ": "\\d{3}[\\dA-Z]{13}",
57 "KW": "[A-Z]{4}[\\dA-Z]{22}",
58 "LV": "[A-Z]{4}[\\dA-Z]{13}",
59 "LB": "\\d{4}[\\dA-Z]{20}",
60 "LI": "\\d{5}[\\dA-Z]{12}",
62 "LU": "\\d{3}[\\dA-Z]{13}",
63 "MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
64 "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
66 "MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
67 "MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
68 "MD": "[\\dA-Z]{2}\\d{18}",
70 "NL": "[A-Z]{4}\\d{10}",
72 "PK": "[\\dA-Z]{4}\\d{16}",
73 "PS": "[\\dA-Z]{4}\\d{21}",
76 "RO": "[A-Z]{4}[\\dA-Z]{16}",
77 "SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
78 "SA": "\\d{2}[\\dA-Z]{18}",
84 "CH": "\\d{5}[\\dA-Z]{12}",
86 "TR": "\\d{5}[\\dA-Z]{17}",
87 "AE": "\\d{3}\\d{16}",
88 "GB": "[A-Z]{4}\\d{14}",
89 "VG": "[\\dA-Z]{4}\\d{16}"
92 bbanpattern
= bbancountrypatterns
[countrycode
];
93 // As new countries will start using IBAN in the
94 // future, we only check if the countrycode is known.
95 // This prevents false negatives, while almost all
96 // false positives introduced by this, will be caught
97 // by the checksum validation below anyway.
98 // Strict checking should return FALSE for unknown
100 if (typeof bbanpattern
!== "undefined") {
101 ibanregexp
= new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern
+ "$", "");
102 if (!(ibanregexp
.test(iban
))) {
103 return false; // invalid country specific format
107 // now check the checksum, first convert to digits
108 ibancheck
= iban
.substring(4, iban
.length
) + iban
.substring(0, 4);
109 for (i
= 0; i
< ibancheck
.length
; i
++) {
110 charAt
= ibancheck
.charAt(i
);
111 if (charAt
!== "0") {
112 leadingZeroes
= false;
114 if (!leadingZeroes
) {
115 ibancheckdigits
+= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(charAt
);
119 // calculate the result of: ibancheckdigits % 97
120 for (p
= 0; p
< ibancheckdigits
.length
; p
++) {
121 cChar
= ibancheckdigits
.charAt(p
);
122 cOperator
= "" + cRest
+ "" + cChar
;
123 cRest
= cOperator
% 97;
126 }, "Please specify a valid IBAN");