You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
5.1 KiB
138 lines
5.1 KiB
import assertString from './util/assertString'; |
|
/** |
|
* List of country codes with |
|
* corresponding IBAN regular expression |
|
* Reference: https://en.wikipedia.org/wiki/International_Bank_Account_Number |
|
*/ |
|
|
|
var ibanRegexThroughCountryCode = { |
|
AD: /^(AD[0-9]{2})\d{8}[A-Z0-9]{12}$/, |
|
AE: /^(AE[0-9]{2})\d{3}\d{16}$/, |
|
AL: /^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/, |
|
AT: /^(AT[0-9]{2})\d{16}$/, |
|
AZ: /^(AZ[0-9]{2})[A-Z0-9]{4}\d{20}$/, |
|
BA: /^(BA[0-9]{2})\d{16}$/, |
|
BE: /^(BE[0-9]{2})\d{12}$/, |
|
BG: /^(BG[0-9]{2})[A-Z]{4}\d{6}[A-Z0-9]{8}$/, |
|
BH: /^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/, |
|
BR: /^(BR[0-9]{2})\d{23}[A-Z]{1}[A-Z0-9]{1}$/, |
|
BY: /^(BY[0-9]{2})[A-Z0-9]{4}\d{20}$/, |
|
CH: /^(CH[0-9]{2})\d{5}[A-Z0-9]{12}$/, |
|
CR: /^(CR[0-9]{2})\d{18}$/, |
|
CY: /^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/, |
|
CZ: /^(CZ[0-9]{2})\d{20}$/, |
|
DE: /^(DE[0-9]{2})\d{18}$/, |
|
DK: /^(DK[0-9]{2})\d{14}$/, |
|
DO: /^(DO[0-9]{2})[A-Z]{4}\d{20}$/, |
|
EE: /^(EE[0-9]{2})\d{16}$/, |
|
EG: /^(EG[0-9]{2})\d{25}$/, |
|
ES: /^(ES[0-9]{2})\d{20}$/, |
|
FI: /^(FI[0-9]{2})\d{14}$/, |
|
FO: /^(FO[0-9]{2})\d{14}$/, |
|
FR: /^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/, |
|
GB: /^(GB[0-9]{2})[A-Z]{4}\d{14}$/, |
|
GE: /^(GE[0-9]{2})[A-Z0-9]{2}\d{16}$/, |
|
GI: /^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/, |
|
GL: /^(GL[0-9]{2})\d{14}$/, |
|
GR: /^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/, |
|
GT: /^(GT[0-9]{2})[A-Z0-9]{4}[A-Z0-9]{20}$/, |
|
HR: /^(HR[0-9]{2})\d{17}$/, |
|
HU: /^(HU[0-9]{2})\d{24}$/, |
|
IE: /^(IE[0-9]{2})[A-Z0-9]{4}\d{14}$/, |
|
IL: /^(IL[0-9]{2})\d{19}$/, |
|
IQ: /^(IQ[0-9]{2})[A-Z]{4}\d{15}$/, |
|
IR: /^(IR[0-9]{2})0\d{2}0\d{18}$/, |
|
IS: /^(IS[0-9]{2})\d{22}$/, |
|
IT: /^(IT[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/, |
|
JO: /^(JO[0-9]{2})[A-Z]{4}\d{22}$/, |
|
KW: /^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/, |
|
KZ: /^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/, |
|
LB: /^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/, |
|
LC: /^(LC[0-9]{2})[A-Z]{4}[A-Z0-9]{24}$/, |
|
LI: /^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/, |
|
LT: /^(LT[0-9]{2})\d{16}$/, |
|
LU: /^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/, |
|
LV: /^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/, |
|
MC: /^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/, |
|
MD: /^(MD[0-9]{2})[A-Z0-9]{20}$/, |
|
ME: /^(ME[0-9]{2})\d{18}$/, |
|
MK: /^(MK[0-9]{2})\d{3}[A-Z0-9]{10}\d{2}$/, |
|
MR: /^(MR[0-9]{2})\d{23}$/, |
|
MT: /^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/, |
|
MU: /^(MU[0-9]{2})[A-Z]{4}\d{19}[A-Z]{3}$/, |
|
MZ: /^(MZ[0-9]{2})\d{21}$/, |
|
NL: /^(NL[0-9]{2})[A-Z]{4}\d{10}$/, |
|
NO: /^(NO[0-9]{2})\d{11}$/, |
|
PK: /^(PK[0-9]{2})[A-Z0-9]{4}\d{16}$/, |
|
PL: /^(PL[0-9]{2})\d{24}$/, |
|
PS: /^(PS[0-9]{2})[A-Z0-9]{4}\d{21}$/, |
|
PT: /^(PT[0-9]{2})\d{21}$/, |
|
QA: /^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/, |
|
RO: /^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/, |
|
RS: /^(RS[0-9]{2})\d{18}$/, |
|
SA: /^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/, |
|
SC: /^(SC[0-9]{2})[A-Z]{4}\d{20}[A-Z]{3}$/, |
|
SE: /^(SE[0-9]{2})\d{20}$/, |
|
SI: /^(SI[0-9]{2})\d{15}$/, |
|
SK: /^(SK[0-9]{2})\d{20}$/, |
|
SM: /^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/, |
|
SV: /^(SV[0-9]{2})[A-Z0-9]{4}\d{20}$/, |
|
TL: /^(TL[0-9]{2})\d{19}$/, |
|
TN: /^(TN[0-9]{2})\d{20}$/, |
|
TR: /^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/, |
|
UA: /^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/, |
|
VA: /^(VA[0-9]{2})\d{18}$/, |
|
VG: /^(VG[0-9]{2})[A-Z0-9]{4}\d{16}$/, |
|
XK: /^(XK[0-9]{2})\d{16}$/ |
|
}; |
|
/** |
|
* Check whether string has correct universal IBAN format |
|
* The IBAN consists of up to 34 alphanumeric characters, as follows: |
|
* Country Code using ISO 3166-1 alpha-2, two letters |
|
* check digits, two digits and |
|
* Basic Bank Account Number (BBAN), up to 30 alphanumeric characters. |
|
* NOTE: Permitted IBAN characters are: digits [0-9] and the 26 latin alphabetic [A-Z] |
|
* |
|
* @param {string} str - string under validation |
|
* @return {boolean} |
|
*/ |
|
|
|
function hasValidIbanFormat(str) { |
|
// Strip white spaces and hyphens |
|
var strippedStr = str.replace(/[\s\-]+/gi, '').toUpperCase(); |
|
var isoCountryCode = strippedStr.slice(0, 2).toUpperCase(); |
|
return isoCountryCode in ibanRegexThroughCountryCode && ibanRegexThroughCountryCode[isoCountryCode].test(strippedStr); |
|
} |
|
/** |
|
* Check whether string has valid IBAN Checksum |
|
* by performing basic mod-97 operation and |
|
* the remainder should equal 1 |
|
* -- Start by rearranging the IBAN by moving the four initial characters to the end of the string |
|
* -- Replace each letter in the string with two digits, A -> 10, B = 11, Z = 35 |
|
* -- Interpret the string as a decimal integer and |
|
* -- compute the remainder on division by 97 (mod 97) |
|
* Reference: https://en.wikipedia.org/wiki/International_Bank_Account_Number |
|
* |
|
* @param {string} str |
|
* @return {boolean} |
|
*/ |
|
|
|
|
|
function hasValidIbanChecksum(str) { |
|
var strippedStr = str.replace(/[^A-Z0-9]+/gi, '').toUpperCase(); // Keep only digits and A-Z latin alphabetic |
|
|
|
var rearranged = strippedStr.slice(4) + strippedStr.slice(0, 4); |
|
var alphaCapsReplacedWithDigits = rearranged.replace(/[A-Z]/g, function (_char) { |
|
return _char.charCodeAt(0) - 55; |
|
}); |
|
var remainder = alphaCapsReplacedWithDigits.match(/\d{1,7}/g).reduce(function (acc, value) { |
|
return Number(acc + value) % 97; |
|
}, ''); |
|
return remainder === 1; |
|
} |
|
|
|
export default function isIBAN(str) { |
|
assertString(str); |
|
return hasValidIbanFormat(str) && hasValidIbanChecksum(str); |
|
} |
|
export var locales = Object.keys(ibanRegexThroughCountryCode); |