isIBAN.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = isIBAN;
  6. exports.locales = void 0;
  7. var _assertString = _interopRequireDefault(require("./util/assertString"));
  8. var _includesArray = _interopRequireDefault(require("./util/includesArray"));
  9. function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
  10. /**
  11. * List of country codes with
  12. * corresponding IBAN regular expression
  13. * Reference: https://en.wikipedia.org/wiki/International_Bank_Account_Number
  14. */
  15. var ibanRegexThroughCountryCode = {
  16. AD: /^(AD[0-9]{2})\d{8}[A-Z0-9]{12}$/,
  17. AE: /^(AE[0-9]{2})\d{3}\d{16}$/,
  18. AL: /^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/,
  19. AT: /^(AT[0-9]{2})\d{16}$/,
  20. AZ: /^(AZ[0-9]{2})[A-Z0-9]{4}\d{20}$/,
  21. BA: /^(BA[0-9]{2})\d{16}$/,
  22. BE: /^(BE[0-9]{2})\d{12}$/,
  23. BG: /^(BG[0-9]{2})[A-Z]{4}\d{6}[A-Z0-9]{8}$/,
  24. BH: /^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/,
  25. BR: /^(BR[0-9]{2})\d{23}[A-Z]{1}[A-Z0-9]{1}$/,
  26. BY: /^(BY[0-9]{2})[A-Z0-9]{4}\d{20}$/,
  27. CH: /^(CH[0-9]{2})\d{5}[A-Z0-9]{12}$/,
  28. CR: /^(CR[0-9]{2})\d{18}$/,
  29. CY: /^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/,
  30. CZ: /^(CZ[0-9]{2})\d{20}$/,
  31. DE: /^(DE[0-9]{2})\d{18}$/,
  32. DK: /^(DK[0-9]{2})\d{14}$/,
  33. DO: /^(DO[0-9]{2})[A-Z]{4}\d{20}$/,
  34. DZ: /^(DZ\d{24})$/,
  35. EE: /^(EE[0-9]{2})\d{16}$/,
  36. EG: /^(EG[0-9]{2})\d{25}$/,
  37. ES: /^(ES[0-9]{2})\d{20}$/,
  38. FI: /^(FI[0-9]{2})\d{14}$/,
  39. FO: /^(FO[0-9]{2})\d{14}$/,
  40. FR: /^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
  41. GB: /^(GB[0-9]{2})[A-Z]{4}\d{14}$/,
  42. GE: /^(GE[0-9]{2})[A-Z0-9]{2}\d{16}$/,
  43. GI: /^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/,
  44. GL: /^(GL[0-9]{2})\d{14}$/,
  45. GR: /^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/,
  46. GT: /^(GT[0-9]{2})[A-Z0-9]{4}[A-Z0-9]{20}$/,
  47. HR: /^(HR[0-9]{2})\d{17}$/,
  48. HU: /^(HU[0-9]{2})\d{24}$/,
  49. IE: /^(IE[0-9]{2})[A-Z]{4}\d{14}$/,
  50. IL: /^(IL[0-9]{2})\d{19}$/,
  51. IQ: /^(IQ[0-9]{2})[A-Z]{4}\d{15}$/,
  52. IR: /^(IR[0-9]{2})0\d{2}0\d{18}$/,
  53. IS: /^(IS[0-9]{2})\d{22}$/,
  54. IT: /^(IT[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
  55. JO: /^(JO[0-9]{2})[A-Z]{4}\d{22}$/,
  56. KW: /^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/,
  57. KZ: /^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/,
  58. LB: /^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/,
  59. LC: /^(LC[0-9]{2})[A-Z]{4}[A-Z0-9]{24}$/,
  60. LI: /^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/,
  61. LT: /^(LT[0-9]{2})\d{16}$/,
  62. LU: /^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/,
  63. LV: /^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/,
  64. MA: /^(MA[0-9]{26})$/,
  65. MC: /^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
  66. MD: /^(MD[0-9]{2})[A-Z0-9]{20}$/,
  67. ME: /^(ME[0-9]{2})\d{18}$/,
  68. MK: /^(MK[0-9]{2})\d{3}[A-Z0-9]{10}\d{2}$/,
  69. MR: /^(MR[0-9]{2})\d{23}$/,
  70. MT: /^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/,
  71. MU: /^(MU[0-9]{2})[A-Z]{4}\d{19}[A-Z]{3}$/,
  72. MZ: /^(MZ[0-9]{2})\d{21}$/,
  73. NL: /^(NL[0-9]{2})[A-Z]{4}\d{10}$/,
  74. NO: /^(NO[0-9]{2})\d{11}$/,
  75. PK: /^(PK[0-9]{2})[A-Z0-9]{4}\d{16}$/,
  76. PL: /^(PL[0-9]{2})\d{24}$/,
  77. PS: /^(PS[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
  78. PT: /^(PT[0-9]{2})\d{21}$/,
  79. QA: /^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
  80. RO: /^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/,
  81. RS: /^(RS[0-9]{2})\d{18}$/,
  82. SA: /^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/,
  83. SC: /^(SC[0-9]{2})[A-Z]{4}\d{20}[A-Z]{3}$/,
  84. SE: /^(SE[0-9]{2})\d{20}$/,
  85. SI: /^(SI[0-9]{2})\d{15}$/,
  86. SK: /^(SK[0-9]{2})\d{20}$/,
  87. SM: /^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
  88. SV: /^(SV[0-9]{2})[A-Z0-9]{4}\d{20}$/,
  89. TL: /^(TL[0-9]{2})\d{19}$/,
  90. TN: /^(TN[0-9]{2})\d{20}$/,
  91. TR: /^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/,
  92. UA: /^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/,
  93. VA: /^(VA[0-9]{2})\d{18}$/,
  94. VG: /^(VG[0-9]{2})[A-Z]{4}\d{16}$/,
  95. XK: /^(XK[0-9]{2})\d{16}$/
  96. };
  97. /**
  98. * Check if the country codes passed are valid using the
  99. * ibanRegexThroughCountryCode as a reference
  100. *
  101. * @param {array} countryCodeArray
  102. * @return {boolean}
  103. */
  104. function hasOnlyValidCountryCodes(countryCodeArray) {
  105. var countryCodeArrayFilteredWithObjectIbanCode = countryCodeArray.filter(function (countryCode) {
  106. return !(countryCode in ibanRegexThroughCountryCode);
  107. });
  108. if (countryCodeArrayFilteredWithObjectIbanCode.length > 0) {
  109. return false;
  110. }
  111. return true;
  112. }
  113. /**
  114. * Check whether string has correct universal IBAN format
  115. * The IBAN consists of up to 34 alphanumeric characters, as follows:
  116. * Country Code using ISO 3166-1 alpha-2, two letters
  117. * check digits, two digits and
  118. * Basic Bank Account Number (BBAN), up to 30 alphanumeric characters.
  119. * NOTE: Permitted IBAN characters are: digits [0-9] and the 26 latin alphabetic [A-Z]
  120. *
  121. * @param {string} str - string under validation
  122. * @param {object} options - object to pass the countries to be either whitelisted or blacklisted
  123. * @return {boolean}
  124. */
  125. function hasValidIbanFormat(str, options) {
  126. // Strip white spaces and hyphens
  127. var strippedStr = str.replace(/[\s\-]+/gi, '').toUpperCase();
  128. var isoCountryCode = strippedStr.slice(0, 2).toUpperCase();
  129. var isoCountryCodeInIbanRegexCodeObject = isoCountryCode in ibanRegexThroughCountryCode;
  130. if (options.whitelist) {
  131. if (!hasOnlyValidCountryCodes(options.whitelist)) {
  132. return false;
  133. }
  134. var isoCountryCodeInWhiteList = (0, _includesArray.default)(options.whitelist, isoCountryCode);
  135. if (!isoCountryCodeInWhiteList) {
  136. return false;
  137. }
  138. }
  139. if (options.blacklist) {
  140. var isoCountryCodeInBlackList = (0, _includesArray.default)(options.blacklist, isoCountryCode);
  141. if (isoCountryCodeInBlackList) {
  142. return false;
  143. }
  144. }
  145. return isoCountryCodeInIbanRegexCodeObject && ibanRegexThroughCountryCode[isoCountryCode].test(strippedStr);
  146. }
  147. /**
  148. * Check whether string has valid IBAN Checksum
  149. * by performing basic mod-97 operation and
  150. * the remainder should equal 1
  151. * -- Start by rearranging the IBAN by moving the four initial characters to the end of the string
  152. * -- Replace each letter in the string with two digits, A -> 10, B = 11, Z = 35
  153. * -- Interpret the string as a decimal integer and
  154. * -- compute the remainder on division by 97 (mod 97)
  155. * Reference: https://en.wikipedia.org/wiki/International_Bank_Account_Number
  156. *
  157. * @param {string} str
  158. * @return {boolean}
  159. */
  160. function hasValidIbanChecksum(str) {
  161. var strippedStr = str.replace(/[^A-Z0-9]+/gi, '').toUpperCase(); // Keep only digits and A-Z latin alphabetic
  162. var rearranged = strippedStr.slice(4) + strippedStr.slice(0, 4);
  163. var alphaCapsReplacedWithDigits = rearranged.replace(/[A-Z]/g, function (char) {
  164. return char.charCodeAt(0) - 55;
  165. });
  166. var remainder = alphaCapsReplacedWithDigits.match(/\d{1,7}/g).reduce(function (acc, value) {
  167. return Number(acc + value) % 97;
  168. }, '');
  169. return remainder === 1;
  170. }
  171. function isIBAN(str) {
  172. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  173. (0, _assertString.default)(str);
  174. return hasValidIbanFormat(str, options) && hasValidIbanChecksum(str);
  175. }
  176. var locales = exports.locales = Object.keys(ibanRegexThroughCountryCode);