isTaxID.js 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563
  1. "use strict";
  2. function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = isTaxID;
  7. var _assertString = _interopRequireDefault(require("./util/assertString"));
  8. var algorithms = _interopRequireWildcard(require("./util/algorithms"));
  9. var _isDate = _interopRequireDefault(require("./isDate"));
  10. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
  11. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  12. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  13. function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
  14. function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
  15. function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  16. function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
  17. function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
  18. function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  19. /**
  20. * TIN Validation
  21. * Validates Tax Identification Numbers (TINs) from the US, EU member states and the United Kingdom.
  22. *
  23. * EU-UK:
  24. * National TIN validity is calculated using public algorithms as made available by DG TAXUD.
  25. *
  26. * See `https://ec.europa.eu/taxation_customs/tin/specs/FS-TIN%20Algorithms-Public.docx` for more information.
  27. *
  28. * US:
  29. * An Employer Identification Number (EIN), also known as a Federal Tax Identification Number,
  30. * is used to identify a business entity.
  31. *
  32. * NOTES:
  33. * - Prefix 47 is being reserved for future use
  34. * - Prefixes 26, 27, 45, 46 and 47 were previously assigned by the Philadelphia campus.
  35. *
  36. * See `http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/How-EINs-are-Assigned-and-Valid-EIN-Prefixes`
  37. * for more information.
  38. */
  39. // Locale functions
  40. /*
  41. * bg-BG validation function
  42. * (Edinen graždanski nomer (EGN/ЕГН), persons only)
  43. * Checks if birth date (first six digits) is valid and calculates check (last) digit
  44. */
  45. function bgBgCheck(tin) {
  46. // Extract full year, normalize month and check birth date validity
  47. var century_year = tin.slice(0, 2);
  48. var month = parseInt(tin.slice(2, 4), 10);
  49. if (month > 40) {
  50. month -= 40;
  51. century_year = "20".concat(century_year);
  52. } else if (month > 20) {
  53. month -= 20;
  54. century_year = "18".concat(century_year);
  55. } else {
  56. century_year = "19".concat(century_year);
  57. }
  58. if (month < 10) {
  59. month = "0".concat(month);
  60. }
  61. var date = "".concat(century_year, "/").concat(month, "/").concat(tin.slice(4, 6));
  62. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  63. return false;
  64. } // split digits into an array for further processing
  65. var digits = tin.split('').map(function (a) {
  66. return parseInt(a, 10);
  67. }); // Calculate checksum by multiplying digits with fixed values
  68. var multip_lookup = [2, 4, 8, 5, 10, 9, 7, 3, 6];
  69. var checksum = 0;
  70. for (var i = 0; i < multip_lookup.length; i++) {
  71. checksum += digits[i] * multip_lookup[i];
  72. }
  73. checksum = checksum % 11 === 10 ? 0 : checksum % 11;
  74. return checksum === digits[9];
  75. }
  76. /**
  77. * Check if an input is a valid Canadian SIN (Social Insurance Number)
  78. *
  79. * The Social Insurance Number (SIN) is a 9 digit number that
  80. * you need to work in Canada or to have access to government programs and benefits.
  81. *
  82. * https://en.wikipedia.org/wiki/Social_Insurance_Number
  83. * https://www.canada.ca/en/employment-social-development/services/sin.html
  84. * https://www.codercrunch.com/challenge/819302488/sin-validator
  85. *
  86. * @param {string} input
  87. * @return {boolean}
  88. */
  89. function isCanadianSIN(input) {
  90. var digitsArray = input.split('');
  91. var even = digitsArray.filter(function (_, idx) {
  92. return idx % 2;
  93. }).map(function (i) {
  94. return Number(i) * 2;
  95. }).join('').split('');
  96. var total = digitsArray.filter(function (_, idx) {
  97. return !(idx % 2);
  98. }).concat(even).map(function (i) {
  99. return Number(i);
  100. }).reduce(function (acc, cur) {
  101. return acc + cur;
  102. });
  103. return total % 10 === 0;
  104. }
  105. /*
  106. * cs-CZ validation function
  107. * (Rodné číslo (RČ), persons only)
  108. * Checks if birth date (first six digits) is valid and divisibility by 11
  109. * Material not in DG TAXUD document sourced from:
  110. * -`https://lorenc.info/3MA381/overeni-spravnosti-rodneho-cisla.htm`
  111. * -`https://www.mvcr.cz/clanek/rady-a-sluzby-dokumenty-rodne-cislo.aspx`
  112. */
  113. function csCzCheck(tin) {
  114. tin = tin.replace(/\W/, ''); // Extract full year from TIN length
  115. var full_year = parseInt(tin.slice(0, 2), 10);
  116. if (tin.length === 10) {
  117. if (full_year < 54) {
  118. full_year = "20".concat(full_year);
  119. } else {
  120. full_year = "19".concat(full_year);
  121. }
  122. } else {
  123. if (tin.slice(6) === '000') {
  124. return false;
  125. } // Three-zero serial not assigned before 1954
  126. if (full_year < 54) {
  127. full_year = "19".concat(full_year);
  128. } else {
  129. return false; // No 18XX years seen in any of the resources
  130. }
  131. } // Add missing zero if needed
  132. if (full_year.length === 3) {
  133. full_year = [full_year.slice(0, 2), '0', full_year.slice(2)].join('');
  134. } // Extract month from TIN and normalize
  135. var month = parseInt(tin.slice(2, 4), 10);
  136. if (month > 50) {
  137. month -= 50;
  138. }
  139. if (month > 20) {
  140. // Month-plus-twenty was only introduced in 2004
  141. if (parseInt(full_year, 10) < 2004) {
  142. return false;
  143. }
  144. month -= 20;
  145. }
  146. if (month < 10) {
  147. month = "0".concat(month);
  148. } // Check date validity
  149. var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
  150. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  151. return false;
  152. } // Verify divisibility by 11
  153. if (tin.length === 10) {
  154. if (parseInt(tin, 10) % 11 !== 0) {
  155. // Some numbers up to and including 1985 are still valid if
  156. // check (last) digit equals 0 and modulo of first 9 digits equals 10
  157. var checkdigit = parseInt(tin.slice(0, 9), 10) % 11;
  158. if (parseInt(full_year, 10) < 1986 && checkdigit === 10) {
  159. if (parseInt(tin.slice(9), 10) !== 0) {
  160. return false;
  161. }
  162. } else {
  163. return false;
  164. }
  165. }
  166. }
  167. return true;
  168. }
  169. /*
  170. * de-AT validation function
  171. * (Abgabenkontonummer, persons/entities)
  172. * Verify TIN validity by calling luhnCheck()
  173. */
  174. function deAtCheck(tin) {
  175. return algorithms.luhnCheck(tin);
  176. }
  177. /*
  178. * de-DE validation function
  179. * (Steueridentifikationsnummer (Steuer-IdNr.), persons only)
  180. * Tests for single duplicate/triplicate value, then calculates ISO 7064 check (last) digit
  181. * Partial implementation of spec (same result with both algorithms always)
  182. */
  183. function deDeCheck(tin) {
  184. // Split digits into an array for further processing
  185. var digits = tin.split('').map(function (a) {
  186. return parseInt(a, 10);
  187. }); // Fill array with strings of number positions
  188. var occurences = [];
  189. for (var i = 0; i < digits.length - 1; i++) {
  190. occurences.push('');
  191. for (var j = 0; j < digits.length - 1; j++) {
  192. if (digits[i] === digits[j]) {
  193. occurences[i] += j;
  194. }
  195. }
  196. } // Remove digits with one occurence and test for only one duplicate/triplicate
  197. occurences = occurences.filter(function (a) {
  198. return a.length > 1;
  199. });
  200. if (occurences.length !== 2 && occurences.length !== 3) {
  201. return false;
  202. } // In case of triplicate value only two digits are allowed next to each other
  203. if (occurences[0].length === 3) {
  204. var trip_locations = occurences[0].split('').map(function (a) {
  205. return parseInt(a, 10);
  206. });
  207. var recurrent = 0; // Amount of neighbour occurences
  208. for (var _i = 0; _i < trip_locations.length - 1; _i++) {
  209. if (trip_locations[_i] + 1 === trip_locations[_i + 1]) {
  210. recurrent += 1;
  211. }
  212. }
  213. if (recurrent === 2) {
  214. return false;
  215. }
  216. }
  217. return algorithms.iso7064Check(tin);
  218. }
  219. /*
  220. * dk-DK validation function
  221. * (CPR-nummer (personnummer), persons only)
  222. * Checks if birth date (first six digits) is valid and assigned to century (seventh) digit,
  223. * and calculates check (last) digit
  224. */
  225. function dkDkCheck(tin) {
  226. tin = tin.replace(/\W/, ''); // Extract year, check if valid for given century digit and add century
  227. var year = parseInt(tin.slice(4, 6), 10);
  228. var century_digit = tin.slice(6, 7);
  229. switch (century_digit) {
  230. case '0':
  231. case '1':
  232. case '2':
  233. case '3':
  234. year = "19".concat(year);
  235. break;
  236. case '4':
  237. case '9':
  238. if (year < 37) {
  239. year = "20".concat(year);
  240. } else {
  241. year = "19".concat(year);
  242. }
  243. break;
  244. default:
  245. if (year < 37) {
  246. year = "20".concat(year);
  247. } else if (year > 58) {
  248. year = "18".concat(year);
  249. } else {
  250. return false;
  251. }
  252. break;
  253. } // Add missing zero if needed
  254. if (year.length === 3) {
  255. year = [year.slice(0, 2), '0', year.slice(2)].join('');
  256. } // Check date validity
  257. var date = "".concat(year, "/").concat(tin.slice(2, 4), "/").concat(tin.slice(0, 2));
  258. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  259. return false;
  260. } // Split digits into an array for further processing
  261. var digits = tin.split('').map(function (a) {
  262. return parseInt(a, 10);
  263. });
  264. var checksum = 0;
  265. var weight = 4; // Multiply by weight and add to checksum
  266. for (var i = 0; i < 9; i++) {
  267. checksum += digits[i] * weight;
  268. weight -= 1;
  269. if (weight === 1) {
  270. weight = 7;
  271. }
  272. }
  273. checksum %= 11;
  274. if (checksum === 1) {
  275. return false;
  276. }
  277. return checksum === 0 ? digits[9] === 0 : digits[9] === 11 - checksum;
  278. }
  279. /*
  280. * el-CY validation function
  281. * (Arithmos Forologikou Mitroou (AFM/ΑΦΜ), persons only)
  282. * Verify TIN validity by calculating ASCII value of check (last) character
  283. */
  284. function elCyCheck(tin) {
  285. // split digits into an array for further processing
  286. var digits = tin.slice(0, 8).split('').map(function (a) {
  287. return parseInt(a, 10);
  288. });
  289. var checksum = 0; // add digits in even places
  290. for (var i = 1; i < digits.length; i += 2) {
  291. checksum += digits[i];
  292. } // add digits in odd places
  293. for (var _i2 = 0; _i2 < digits.length; _i2 += 2) {
  294. if (digits[_i2] < 2) {
  295. checksum += 1 - digits[_i2];
  296. } else {
  297. checksum += 2 * (digits[_i2] - 2) + 5;
  298. if (digits[_i2] > 4) {
  299. checksum += 2;
  300. }
  301. }
  302. }
  303. return String.fromCharCode(checksum % 26 + 65) === tin.charAt(8);
  304. }
  305. /*
  306. * el-GR validation function
  307. * (Arithmos Forologikou Mitroou (AFM/ΑΦΜ), persons/entities)
  308. * Verify TIN validity by calculating check (last) digit
  309. * Algorithm not in DG TAXUD document- sourced from:
  310. * - `http://epixeirisi.gr/%CE%9A%CE%A1%CE%99%CE%A3%CE%99%CE%9C%CE%91-%CE%98%CE%95%CE%9C%CE%91%CE%A4%CE%91-%CE%A6%CE%9F%CE%A1%CE%9F%CE%9B%CE%9F%CE%93%CE%99%CE%91%CE%A3-%CE%9A%CE%91%CE%99-%CE%9B%CE%9F%CE%93%CE%99%CE%A3%CE%A4%CE%99%CE%9A%CE%97%CE%A3/23791/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82-%CE%A6%CE%BF%CF%81%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CE%BA%CE%BF%CF%8D-%CE%9C%CE%B7%CF%84%CF%81%CF%8E%CE%BF%CF%85`
  311. */
  312. function elGrCheck(tin) {
  313. // split digits into an array for further processing
  314. var digits = tin.split('').map(function (a) {
  315. return parseInt(a, 10);
  316. });
  317. var checksum = 0;
  318. for (var i = 0; i < 8; i++) {
  319. checksum += digits[i] * Math.pow(2, 8 - i);
  320. }
  321. return checksum % 11 % 10 === digits[8];
  322. }
  323. /*
  324. * en-GB validation function (should go here if needed)
  325. * (National Insurance Number (NINO) or Unique Taxpayer Reference (UTR),
  326. * persons/entities respectively)
  327. */
  328. /*
  329. * en-IE validation function
  330. * (Personal Public Service Number (PPS No), persons only)
  331. * Verify TIN validity by calculating check (second to last) character
  332. */
  333. function enIeCheck(tin) {
  334. var checksum = algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 7).map(function (a) {
  335. return parseInt(a, 10);
  336. }), 8);
  337. if (tin.length === 9 && tin[8] !== 'W') {
  338. checksum += (tin[8].charCodeAt(0) - 64) * 9;
  339. }
  340. checksum %= 23;
  341. if (checksum === 0) {
  342. return tin[7].toUpperCase() === 'W';
  343. }
  344. return tin[7].toUpperCase() === String.fromCharCode(64 + checksum);
  345. } // Valid US IRS campus prefixes
  346. var enUsCampusPrefix = {
  347. andover: ['10', '12'],
  348. atlanta: ['60', '67'],
  349. austin: ['50', '53'],
  350. brookhaven: ['01', '02', '03', '04', '05', '06', '11', '13', '14', '16', '21', '22', '23', '25', '34', '51', '52', '54', '55', '56', '57', '58', '59', '65'],
  351. cincinnati: ['30', '32', '35', '36', '37', '38', '61'],
  352. fresno: ['15', '24'],
  353. internet: ['20', '26', '27', '45', '46', '47'],
  354. kansas: ['40', '44'],
  355. memphis: ['94', '95'],
  356. ogden: ['80', '90'],
  357. philadelphia: ['33', '39', '41', '42', '43', '46', '48', '62', '63', '64', '66', '68', '71', '72', '73', '74', '75', '76', '77', '81', '82', '83', '84', '85', '86', '87', '88', '91', '92', '93', '98', '99'],
  358. sba: ['31']
  359. }; // Return an array of all US IRS campus prefixes
  360. function enUsGetPrefixes() {
  361. var prefixes = [];
  362. for (var location in enUsCampusPrefix) {
  363. // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
  364. // istanbul ignore else
  365. if (enUsCampusPrefix.hasOwnProperty(location)) {
  366. prefixes.push.apply(prefixes, _toConsumableArray(enUsCampusPrefix[location]));
  367. }
  368. }
  369. return prefixes;
  370. }
  371. /*
  372. * en-US validation function
  373. * Verify that the TIN starts with a valid IRS campus prefix
  374. */
  375. function enUsCheck(tin) {
  376. return enUsGetPrefixes().indexOf(tin.slice(0, 2)) !== -1;
  377. }
  378. /*
  379. * es-ES validation function
  380. * (Documento Nacional de Identidad (DNI)
  381. * or Número de Identificación de Extranjero (NIE), persons only)
  382. * Verify TIN validity by calculating check (last) character
  383. */
  384. function esEsCheck(tin) {
  385. // Split characters into an array for further processing
  386. var chars = tin.toUpperCase().split(''); // Replace initial letter if needed
  387. if (isNaN(parseInt(chars[0], 10)) && chars.length > 1) {
  388. var lead_replace = 0;
  389. switch (chars[0]) {
  390. case 'Y':
  391. lead_replace = 1;
  392. break;
  393. case 'Z':
  394. lead_replace = 2;
  395. break;
  396. default:
  397. }
  398. chars.splice(0, 1, lead_replace); // Fill with zeros if smaller than proper
  399. } else {
  400. while (chars.length < 9) {
  401. chars.unshift(0);
  402. }
  403. } // Calculate checksum and check according to lookup
  404. var lookup = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E'];
  405. chars = chars.join('');
  406. var checksum = parseInt(chars.slice(0, 8), 10) % 23;
  407. return chars[8] === lookup[checksum];
  408. }
  409. /*
  410. * et-EE validation function
  411. * (Isikukood (IK), persons only)
  412. * Checks if birth date (century digit and six following) is valid and calculates check (last) digit
  413. * Material not in DG TAXUD document sourced from:
  414. * - `https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf`
  415. */
  416. function etEeCheck(tin) {
  417. // Extract year and add century
  418. var full_year = tin.slice(1, 3);
  419. var century_digit = tin.slice(0, 1);
  420. switch (century_digit) {
  421. case '1':
  422. case '2':
  423. full_year = "18".concat(full_year);
  424. break;
  425. case '3':
  426. case '4':
  427. full_year = "19".concat(full_year);
  428. break;
  429. default:
  430. full_year = "20".concat(full_year);
  431. break;
  432. } // Check date validity
  433. var date = "".concat(full_year, "/").concat(tin.slice(3, 5), "/").concat(tin.slice(5, 7));
  434. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  435. return false;
  436. } // Split digits into an array for further processing
  437. var digits = tin.split('').map(function (a) {
  438. return parseInt(a, 10);
  439. });
  440. var checksum = 0;
  441. var weight = 1; // Multiply by weight and add to checksum
  442. for (var i = 0; i < 10; i++) {
  443. checksum += digits[i] * weight;
  444. weight += 1;
  445. if (weight === 10) {
  446. weight = 1;
  447. }
  448. } // Do again if modulo 11 of checksum is 10
  449. if (checksum % 11 === 10) {
  450. checksum = 0;
  451. weight = 3;
  452. for (var _i3 = 0; _i3 < 10; _i3++) {
  453. checksum += digits[_i3] * weight;
  454. weight += 1;
  455. if (weight === 10) {
  456. weight = 1;
  457. }
  458. }
  459. if (checksum % 11 === 10) {
  460. return digits[10] === 0;
  461. }
  462. }
  463. return checksum % 11 === digits[10];
  464. }
  465. /*
  466. * fi-FI validation function
  467. * (Henkilötunnus (HETU), persons only)
  468. * Checks if birth date (first six digits plus century symbol) is valid
  469. * and calculates check (last) digit
  470. */
  471. function fiFiCheck(tin) {
  472. // Extract year and add century
  473. var full_year = tin.slice(4, 6);
  474. var century_symbol = tin.slice(6, 7);
  475. switch (century_symbol) {
  476. case '+':
  477. full_year = "18".concat(full_year);
  478. break;
  479. case '-':
  480. full_year = "19".concat(full_year);
  481. break;
  482. default:
  483. full_year = "20".concat(full_year);
  484. break;
  485. } // Check date validity
  486. var date = "".concat(full_year, "/").concat(tin.slice(2, 4), "/").concat(tin.slice(0, 2));
  487. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  488. return false;
  489. } // Calculate check character
  490. var checksum = parseInt(tin.slice(0, 6) + tin.slice(7, 10), 10) % 31;
  491. if (checksum < 10) {
  492. return checksum === parseInt(tin.slice(10), 10);
  493. }
  494. checksum -= 10;
  495. var letters_lookup = ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'];
  496. return letters_lookup[checksum] === tin.slice(10);
  497. }
  498. /*
  499. * fr/nl-BE validation function
  500. * (Numéro national (N.N.), persons only)
  501. * Checks if birth date (first six digits) is valid and calculates check (last two) digits
  502. */
  503. function frBeCheck(tin) {
  504. // Zero month/day value is acceptable
  505. if (tin.slice(2, 4) !== '00' || tin.slice(4, 6) !== '00') {
  506. // Extract date from first six digits of TIN
  507. var date = "".concat(tin.slice(0, 2), "/").concat(tin.slice(2, 4), "/").concat(tin.slice(4, 6));
  508. if (!(0, _isDate.default)(date, 'YY/MM/DD')) {
  509. return false;
  510. }
  511. }
  512. var checksum = 97 - parseInt(tin.slice(0, 9), 10) % 97;
  513. var checkdigits = parseInt(tin.slice(9, 11), 10);
  514. if (checksum !== checkdigits) {
  515. checksum = 97 - parseInt("2".concat(tin.slice(0, 9)), 10) % 97;
  516. if (checksum !== checkdigits) {
  517. return false;
  518. }
  519. }
  520. return true;
  521. }
  522. /*
  523. * fr-FR validation function
  524. * (Numéro fiscal de référence (numéro SPI), persons only)
  525. * Verify TIN validity by calculating check (last three) digits
  526. */
  527. function frFrCheck(tin) {
  528. tin = tin.replace(/\s/g, '');
  529. var checksum = parseInt(tin.slice(0, 10), 10) % 511;
  530. var checkdigits = parseInt(tin.slice(10, 13), 10);
  531. return checksum === checkdigits;
  532. }
  533. /*
  534. * fr/lb-LU validation function
  535. * (numéro d’identification personnelle, persons only)
  536. * Verify birth date validity and run Luhn and Verhoeff checks
  537. */
  538. function frLuCheck(tin) {
  539. // Extract date and check validity
  540. var date = "".concat(tin.slice(0, 4), "/").concat(tin.slice(4, 6), "/").concat(tin.slice(6, 8));
  541. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  542. return false;
  543. } // Run Luhn check
  544. if (!algorithms.luhnCheck(tin.slice(0, 12))) {
  545. return false;
  546. } // Remove Luhn check digit and run Verhoeff check
  547. return algorithms.verhoeffCheck("".concat(tin.slice(0, 11)).concat(tin[12]));
  548. }
  549. /*
  550. * hr-HR validation function
  551. * (Osobni identifikacijski broj (OIB), persons/entities)
  552. * Verify TIN validity by calling iso7064Check(digits)
  553. */
  554. function hrHrCheck(tin) {
  555. return algorithms.iso7064Check(tin);
  556. }
  557. /*
  558. * hu-HU validation function
  559. * (Adóazonosító jel, persons only)
  560. * Verify TIN validity by calculating check (last) digit
  561. */
  562. function huHuCheck(tin) {
  563. // split digits into an array for further processing
  564. var digits = tin.split('').map(function (a) {
  565. return parseInt(a, 10);
  566. });
  567. var checksum = 8;
  568. for (var i = 1; i < 9; i++) {
  569. checksum += digits[i] * (i + 1);
  570. }
  571. return checksum % 11 === digits[9];
  572. }
  573. /*
  574. * lt-LT validation function (should go here if needed)
  575. * (Asmens kodas, persons/entities respectively)
  576. * Current validation check is alias of etEeCheck- same format applies
  577. */
  578. /*
  579. * it-IT first/last name validity check
  580. * Accepts it-IT TIN-encoded names as a three-element character array and checks their validity
  581. * Due to lack of clarity between resources ("Are only Italian consonants used?
  582. * What happens if a person has X in their name?" etc.) only two test conditions
  583. * have been implemented:
  584. * Vowels may only be followed by other vowels or an X character
  585. * and X characters after vowels may only be followed by other X characters.
  586. */
  587. function itItNameCheck(name) {
  588. // true at the first occurence of a vowel
  589. var vowelflag = false; // true at the first occurence of an X AFTER vowel
  590. // (to properly handle last names with X as consonant)
  591. var xflag = false;
  592. for (var i = 0; i < 3; i++) {
  593. if (!vowelflag && /[AEIOU]/.test(name[i])) {
  594. vowelflag = true;
  595. } else if (!xflag && vowelflag && name[i] === 'X') {
  596. xflag = true;
  597. } else if (i > 0) {
  598. if (vowelflag && !xflag) {
  599. if (!/[AEIOU]/.test(name[i])) {
  600. return false;
  601. }
  602. }
  603. if (xflag) {
  604. if (!/X/.test(name[i])) {
  605. return false;
  606. }
  607. }
  608. }
  609. }
  610. return true;
  611. }
  612. /*
  613. * it-IT validation function
  614. * (Codice fiscale (TIN-IT), persons only)
  615. * Verify name, birth date and codice catastale validity
  616. * and calculate check character.
  617. * Material not in DG-TAXUD document sourced from:
  618. * `https://en.wikipedia.org/wiki/Italian_fiscal_code`
  619. */
  620. function itItCheck(tin) {
  621. // Capitalize and split characters into an array for further processing
  622. var chars = tin.toUpperCase().split(''); // Check first and last name validity calling itItNameCheck()
  623. if (!itItNameCheck(chars.slice(0, 3))) {
  624. return false;
  625. }
  626. if (!itItNameCheck(chars.slice(3, 6))) {
  627. return false;
  628. } // Convert letters in number spaces back to numbers if any
  629. var number_locations = [6, 7, 9, 10, 12, 13, 14];
  630. var number_replace = {
  631. L: '0',
  632. M: '1',
  633. N: '2',
  634. P: '3',
  635. Q: '4',
  636. R: '5',
  637. S: '6',
  638. T: '7',
  639. U: '8',
  640. V: '9'
  641. };
  642. for (var _i4 = 0, _number_locations = number_locations; _i4 < _number_locations.length; _i4++) {
  643. var i = _number_locations[_i4];
  644. if (chars[i] in number_replace) {
  645. chars.splice(i, 1, number_replace[chars[i]]);
  646. }
  647. } // Extract month and day, and check date validity
  648. var month_replace = {
  649. A: '01',
  650. B: '02',
  651. C: '03',
  652. D: '04',
  653. E: '05',
  654. H: '06',
  655. L: '07',
  656. M: '08',
  657. P: '09',
  658. R: '10',
  659. S: '11',
  660. T: '12'
  661. };
  662. var month = month_replace[chars[8]];
  663. var day = parseInt(chars[9] + chars[10], 10);
  664. if (day > 40) {
  665. day -= 40;
  666. }
  667. if (day < 10) {
  668. day = "0".concat(day);
  669. }
  670. var date = "".concat(chars[6]).concat(chars[7], "/").concat(month, "/").concat(day);
  671. if (!(0, _isDate.default)(date, 'YY/MM/DD')) {
  672. return false;
  673. } // Calculate check character by adding up even and odd characters as numbers
  674. var checksum = 0;
  675. for (var _i5 = 1; _i5 < chars.length - 1; _i5 += 2) {
  676. var char_to_int = parseInt(chars[_i5], 10);
  677. if (isNaN(char_to_int)) {
  678. char_to_int = chars[_i5].charCodeAt(0) - 65;
  679. }
  680. checksum += char_to_int;
  681. }
  682. var odd_convert = {
  683. // Maps of characters at odd places
  684. A: 1,
  685. B: 0,
  686. C: 5,
  687. D: 7,
  688. E: 9,
  689. F: 13,
  690. G: 15,
  691. H: 17,
  692. I: 19,
  693. J: 21,
  694. K: 2,
  695. L: 4,
  696. M: 18,
  697. N: 20,
  698. O: 11,
  699. P: 3,
  700. Q: 6,
  701. R: 8,
  702. S: 12,
  703. T: 14,
  704. U: 16,
  705. V: 10,
  706. W: 22,
  707. X: 25,
  708. Y: 24,
  709. Z: 23,
  710. 0: 1,
  711. 1: 0
  712. };
  713. for (var _i6 = 0; _i6 < chars.length - 1; _i6 += 2) {
  714. var _char_to_int = 0;
  715. if (chars[_i6] in odd_convert) {
  716. _char_to_int = odd_convert[chars[_i6]];
  717. } else {
  718. var multiplier = parseInt(chars[_i6], 10);
  719. _char_to_int = 2 * multiplier + 1;
  720. if (multiplier > 4) {
  721. _char_to_int += 2;
  722. }
  723. }
  724. checksum += _char_to_int;
  725. }
  726. if (String.fromCharCode(65 + checksum % 26) !== chars[15]) {
  727. return false;
  728. }
  729. return true;
  730. }
  731. /*
  732. * lv-LV validation function
  733. * (Personas kods (PK), persons only)
  734. * Check validity of birth date and calculate check (last) digit
  735. * Support only for old format numbers (not starting with '32', issued before 2017/07/01)
  736. * Material not in DG TAXUD document sourced from:
  737. * `https://boot.ritakafija.lv/forums/index.php?/topic/88314-personas-koda-algoritms-%C4%8Deksumma/`
  738. */
  739. function lvLvCheck(tin) {
  740. tin = tin.replace(/\W/, ''); // Extract date from TIN
  741. var day = tin.slice(0, 2);
  742. if (day !== '32') {
  743. // No date/checksum check if new format
  744. var month = tin.slice(2, 4);
  745. if (month !== '00') {
  746. // No date check if unknown month
  747. var full_year = tin.slice(4, 6);
  748. switch (tin[6]) {
  749. case '0':
  750. full_year = "18".concat(full_year);
  751. break;
  752. case '1':
  753. full_year = "19".concat(full_year);
  754. break;
  755. default:
  756. full_year = "20".concat(full_year);
  757. break;
  758. } // Check date validity
  759. var date = "".concat(full_year, "/").concat(tin.slice(2, 4), "/").concat(day);
  760. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  761. return false;
  762. }
  763. } // Calculate check digit
  764. var checksum = 1101;
  765. var multip_lookup = [1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  766. for (var i = 0; i < tin.length - 1; i++) {
  767. checksum -= parseInt(tin[i], 10) * multip_lookup[i];
  768. }
  769. return parseInt(tin[10], 10) === checksum % 11;
  770. }
  771. return true;
  772. }
  773. /*
  774. * mt-MT validation function
  775. * (Identity Card Number or Unique Taxpayer Reference, persons/entities)
  776. * Verify Identity Card Number structure (no other tests found)
  777. */
  778. function mtMtCheck(tin) {
  779. if (tin.length !== 9) {
  780. // No tests for UTR
  781. var chars = tin.toUpperCase().split(''); // Fill with zeros if smaller than proper
  782. while (chars.length < 8) {
  783. chars.unshift(0);
  784. } // Validate format according to last character
  785. switch (tin[7]) {
  786. case 'A':
  787. case 'P':
  788. if (parseInt(chars[6], 10) === 0) {
  789. return false;
  790. }
  791. break;
  792. default:
  793. {
  794. var first_part = parseInt(chars.join('').slice(0, 5), 10);
  795. if (first_part > 32000) {
  796. return false;
  797. }
  798. var second_part = parseInt(chars.join('').slice(5, 7), 10);
  799. if (first_part === second_part) {
  800. return false;
  801. }
  802. }
  803. }
  804. }
  805. return true;
  806. }
  807. /*
  808. * nl-NL validation function
  809. * (Burgerservicenummer (BSN) or Rechtspersonen Samenwerkingsverbanden Informatie Nummer (RSIN),
  810. * persons/entities respectively)
  811. * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
  812. */
  813. function nlNlCheck(tin) {
  814. return algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
  815. return parseInt(a, 10);
  816. }), 9) % 11 === parseInt(tin[8], 10);
  817. }
  818. /*
  819. * pl-PL validation function
  820. * (Powszechny Elektroniczny System Ewidencji Ludności (PESEL)
  821. * or Numer identyfikacji podatkowej (NIP), persons/entities)
  822. * Verify TIN validity by validating birth date (PESEL) and calculating check (last) digit
  823. */
  824. function plPlCheck(tin) {
  825. // NIP
  826. if (tin.length === 10) {
  827. // Calculate last digit by multiplying with lookup
  828. var lookup = [6, 5, 7, 2, 3, 4, 5, 6, 7];
  829. var _checksum = 0;
  830. for (var i = 0; i < lookup.length; i++) {
  831. _checksum += parseInt(tin[i], 10) * lookup[i];
  832. }
  833. _checksum %= 11;
  834. if (_checksum === 10) {
  835. return false;
  836. }
  837. return _checksum === parseInt(tin[9], 10);
  838. } // PESEL
  839. // Extract full year using month
  840. var full_year = tin.slice(0, 2);
  841. var month = parseInt(tin.slice(2, 4), 10);
  842. if (month > 80) {
  843. full_year = "18".concat(full_year);
  844. month -= 80;
  845. } else if (month > 60) {
  846. full_year = "22".concat(full_year);
  847. month -= 60;
  848. } else if (month > 40) {
  849. full_year = "21".concat(full_year);
  850. month -= 40;
  851. } else if (month > 20) {
  852. full_year = "20".concat(full_year);
  853. month -= 20;
  854. } else {
  855. full_year = "19".concat(full_year);
  856. } // Add leading zero to month if needed
  857. if (month < 10) {
  858. month = "0".concat(month);
  859. } // Check date validity
  860. var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
  861. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  862. return false;
  863. } // Calculate last digit by mulitplying with odd one-digit numbers except 5
  864. var checksum = 0;
  865. var multiplier = 1;
  866. for (var _i7 = 0; _i7 < tin.length - 1; _i7++) {
  867. checksum += parseInt(tin[_i7], 10) * multiplier % 10;
  868. multiplier += 2;
  869. if (multiplier > 10) {
  870. multiplier = 1;
  871. } else if (multiplier === 5) {
  872. multiplier += 2;
  873. }
  874. }
  875. checksum = 10 - checksum % 10;
  876. return checksum === parseInt(tin[10], 10);
  877. }
  878. /*
  879. * pt-BR validation function
  880. * (Cadastro de Pessoas Físicas (CPF, persons)
  881. * Cadastro Nacional de Pessoas Jurídicas (CNPJ, entities)
  882. * Both inputs will be validated
  883. */
  884. function ptBrCheck(tin) {
  885. if (tin.length === 11) {
  886. var _sum;
  887. var remainder;
  888. _sum = 0;
  889. if ( // Reject known invalid CPFs
  890. tin === '11111111111' || tin === '22222222222' || tin === '33333333333' || tin === '44444444444' || tin === '55555555555' || tin === '66666666666' || tin === '77777777777' || tin === '88888888888' || tin === '99999999999' || tin === '00000000000') return false;
  891. for (var i = 1; i <= 9; i++) {
  892. _sum += parseInt(tin.substring(i - 1, i), 10) * (11 - i);
  893. }
  894. remainder = _sum * 10 % 11;
  895. if (remainder === 10) remainder = 0;
  896. if (remainder !== parseInt(tin.substring(9, 10), 10)) return false;
  897. _sum = 0;
  898. for (var _i8 = 1; _i8 <= 10; _i8++) {
  899. _sum += parseInt(tin.substring(_i8 - 1, _i8), 10) * (12 - _i8);
  900. }
  901. remainder = _sum * 10 % 11;
  902. if (remainder === 10) remainder = 0;
  903. if (remainder !== parseInt(tin.substring(10, 11), 10)) return false;
  904. return true;
  905. }
  906. if ( // Reject know invalid CNPJs
  907. tin === '00000000000000' || tin === '11111111111111' || tin === '22222222222222' || tin === '33333333333333' || tin === '44444444444444' || tin === '55555555555555' || tin === '66666666666666' || tin === '77777777777777' || tin === '88888888888888' || tin === '99999999999999') {
  908. return false;
  909. }
  910. var length = tin.length - 2;
  911. var identifiers = tin.substring(0, length);
  912. var verificators = tin.substring(length);
  913. var sum = 0;
  914. var pos = length - 7;
  915. for (var _i9 = length; _i9 >= 1; _i9--) {
  916. sum += identifiers.charAt(length - _i9) * pos;
  917. pos -= 1;
  918. if (pos < 2) {
  919. pos = 9;
  920. }
  921. }
  922. var result = sum % 11 < 2 ? 0 : 11 - sum % 11;
  923. if (result !== parseInt(verificators.charAt(0), 10)) {
  924. return false;
  925. }
  926. length += 1;
  927. identifiers = tin.substring(0, length);
  928. sum = 0;
  929. pos = length - 7;
  930. for (var _i10 = length; _i10 >= 1; _i10--) {
  931. sum += identifiers.charAt(length - _i10) * pos;
  932. pos -= 1;
  933. if (pos < 2) {
  934. pos = 9;
  935. }
  936. }
  937. result = sum % 11 < 2 ? 0 : 11 - sum % 11;
  938. if (result !== parseInt(verificators.charAt(1), 10)) {
  939. return false;
  940. }
  941. return true;
  942. }
  943. /*
  944. * pt-PT validation function
  945. * (Número de identificação fiscal (NIF), persons/entities)
  946. * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
  947. */
  948. function ptPtCheck(tin) {
  949. var checksum = 11 - algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
  950. return parseInt(a, 10);
  951. }), 9) % 11;
  952. if (checksum > 9) {
  953. return parseInt(tin[8], 10) === 0;
  954. }
  955. return checksum === parseInt(tin[8], 10);
  956. }
  957. /*
  958. * ro-RO validation function
  959. * (Cod Numeric Personal (CNP) or Cod de înregistrare fiscală (CIF),
  960. * persons only)
  961. * Verify CNP validity by calculating check (last) digit (test not found for CIF)
  962. * Material not in DG TAXUD document sourced from:
  963. * `https://en.wikipedia.org/wiki/National_identification_number#Romania`
  964. */
  965. function roRoCheck(tin) {
  966. if (tin.slice(0, 4) !== '9000') {
  967. // No test found for this format
  968. // Extract full year using century digit if possible
  969. var full_year = tin.slice(1, 3);
  970. switch (tin[0]) {
  971. case '1':
  972. case '2':
  973. full_year = "19".concat(full_year);
  974. break;
  975. case '3':
  976. case '4':
  977. full_year = "18".concat(full_year);
  978. break;
  979. case '5':
  980. case '6':
  981. full_year = "20".concat(full_year);
  982. break;
  983. default:
  984. } // Check date validity
  985. var date = "".concat(full_year, "/").concat(tin.slice(3, 5), "/").concat(tin.slice(5, 7));
  986. if (date.length === 8) {
  987. if (!(0, _isDate.default)(date, 'YY/MM/DD')) {
  988. return false;
  989. }
  990. } else if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  991. return false;
  992. } // Calculate check digit
  993. var digits = tin.split('').map(function (a) {
  994. return parseInt(a, 10);
  995. });
  996. var multipliers = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9];
  997. var checksum = 0;
  998. for (var i = 0; i < multipliers.length; i++) {
  999. checksum += digits[i] * multipliers[i];
  1000. }
  1001. if (checksum % 11 === 10) {
  1002. return digits[12] === 1;
  1003. }
  1004. return digits[12] === checksum % 11;
  1005. }
  1006. return true;
  1007. }
  1008. /*
  1009. * sk-SK validation function
  1010. * (Rodné číslo (RČ) or bezvýznamové identifikačné číslo (BIČ), persons only)
  1011. * Checks validity of pre-1954 birth numbers (rodné číslo) only
  1012. * Due to the introduction of the pseudo-random BIČ it is not possible to test
  1013. * post-1954 birth numbers without knowing whether they are BIČ or RČ beforehand
  1014. */
  1015. function skSkCheck(tin) {
  1016. if (tin.length === 9) {
  1017. tin = tin.replace(/\W/, '');
  1018. if (tin.slice(6) === '000') {
  1019. return false;
  1020. } // Three-zero serial not assigned before 1954
  1021. // Extract full year from TIN length
  1022. var full_year = parseInt(tin.slice(0, 2), 10);
  1023. if (full_year > 53) {
  1024. return false;
  1025. }
  1026. if (full_year < 10) {
  1027. full_year = "190".concat(full_year);
  1028. } else {
  1029. full_year = "19".concat(full_year);
  1030. } // Extract month from TIN and normalize
  1031. var month = parseInt(tin.slice(2, 4), 10);
  1032. if (month > 50) {
  1033. month -= 50;
  1034. }
  1035. if (month < 10) {
  1036. month = "0".concat(month);
  1037. } // Check date validity
  1038. var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
  1039. if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  1040. return false;
  1041. }
  1042. }
  1043. return true;
  1044. }
  1045. /*
  1046. * sl-SI validation function
  1047. * (Davčna številka, persons/entities)
  1048. * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
  1049. */
  1050. function slSiCheck(tin) {
  1051. var checksum = 11 - algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 7).map(function (a) {
  1052. return parseInt(a, 10);
  1053. }), 8) % 11;
  1054. if (checksum === 10) {
  1055. return parseInt(tin[7], 10) === 0;
  1056. }
  1057. return checksum === parseInt(tin[7], 10);
  1058. }
  1059. /*
  1060. * sv-SE validation function
  1061. * (Personnummer or samordningsnummer, persons only)
  1062. * Checks validity of birth date and calls luhnCheck() to validate check (last) digit
  1063. */
  1064. function svSeCheck(tin) {
  1065. // Make copy of TIN and normalize to two-digit year form
  1066. var tin_copy = tin.slice(0);
  1067. if (tin.length > 11) {
  1068. tin_copy = tin_copy.slice(2);
  1069. } // Extract date of birth
  1070. var full_year = '';
  1071. var month = tin_copy.slice(2, 4);
  1072. var day = parseInt(tin_copy.slice(4, 6), 10);
  1073. if (tin.length > 11) {
  1074. full_year = tin.slice(0, 4);
  1075. } else {
  1076. full_year = tin.slice(0, 2);
  1077. if (tin.length === 11 && day < 60) {
  1078. // Extract full year from centenarian symbol
  1079. // Should work just fine until year 10000 or so
  1080. var current_year = new Date().getFullYear().toString();
  1081. var current_century = parseInt(current_year.slice(0, 2), 10);
  1082. current_year = parseInt(current_year, 10);
  1083. if (tin[6] === '-') {
  1084. if (parseInt("".concat(current_century).concat(full_year), 10) > current_year) {
  1085. full_year = "".concat(current_century - 1).concat(full_year);
  1086. } else {
  1087. full_year = "".concat(current_century).concat(full_year);
  1088. }
  1089. } else {
  1090. full_year = "".concat(current_century - 1).concat(full_year);
  1091. if (current_year - parseInt(full_year, 10) < 100) {
  1092. return false;
  1093. }
  1094. }
  1095. }
  1096. } // Normalize day and check date validity
  1097. if (day > 60) {
  1098. day -= 60;
  1099. }
  1100. if (day < 10) {
  1101. day = "0".concat(day);
  1102. }
  1103. var date = "".concat(full_year, "/").concat(month, "/").concat(day);
  1104. if (date.length === 8) {
  1105. if (!(0, _isDate.default)(date, 'YY/MM/DD')) {
  1106. return false;
  1107. }
  1108. } else if (!(0, _isDate.default)(date, 'YYYY/MM/DD')) {
  1109. return false;
  1110. }
  1111. return algorithms.luhnCheck(tin.replace(/\W/, ''));
  1112. } // Locale lookup objects
  1113. /*
  1114. * Tax id regex formats for various locales
  1115. *
  1116. * Where not explicitly specified in DG-TAXUD document both
  1117. * uppercase and lowercase letters are acceptable.
  1118. */
  1119. var taxIdFormat = {
  1120. 'bg-BG': /^\d{10}$/,
  1121. 'cs-CZ': /^\d{6}\/{0,1}\d{3,4}$/,
  1122. 'de-AT': /^\d{9}$/,
  1123. 'de-DE': /^[1-9]\d{10}$/,
  1124. 'dk-DK': /^\d{6}-{0,1}\d{4}$/,
  1125. 'el-CY': /^[09]\d{7}[A-Z]$/,
  1126. 'el-GR': /^([0-4]|[7-9])\d{8}$/,
  1127. 'en-CA': /^\d{9}$/,
  1128. 'en-GB': /^\d{10}$|^(?!GB|NK|TN|ZZ)(?![DFIQUV])[A-Z](?![DFIQUVO])[A-Z]\d{6}[ABCD ]$/i,
  1129. 'en-IE': /^\d{7}[A-W][A-IW]{0,1}$/i,
  1130. 'en-US': /^\d{2}[- ]{0,1}\d{7}$/,
  1131. 'es-ES': /^(\d{0,8}|[XYZKLM]\d{7})[A-HJ-NP-TV-Z]$/i,
  1132. 'et-EE': /^[1-6]\d{6}(00[1-9]|0[1-9][0-9]|[1-6][0-9]{2}|70[0-9]|710)\d$/,
  1133. 'fi-FI': /^\d{6}[-+A]\d{3}[0-9A-FHJ-NPR-Y]$/i,
  1134. 'fr-BE': /^\d{11}$/,
  1135. 'fr-FR': /^[0-3]\d{12}$|^[0-3]\d\s\d{2}(\s\d{3}){3}$/,
  1136. // Conforms both to official spec and provided example
  1137. 'fr-LU': /^\d{13}$/,
  1138. 'hr-HR': /^\d{11}$/,
  1139. 'hu-HU': /^8\d{9}$/,
  1140. 'it-IT': /^[A-Z]{6}[L-NP-V0-9]{2}[A-EHLMPRST][L-NP-V0-9]{2}[A-ILMZ][L-NP-V0-9]{3}[A-Z]$/i,
  1141. 'lv-LV': /^\d{6}-{0,1}\d{5}$/,
  1142. // Conforms both to DG TAXUD spec and original research
  1143. 'mt-MT': /^\d{3,7}[APMGLHBZ]$|^([1-8])\1\d{7}$/i,
  1144. 'nl-NL': /^\d{9}$/,
  1145. 'pl-PL': /^\d{10,11}$/,
  1146. 'pt-BR': /(?:^\d{11}$)|(?:^\d{14}$)/,
  1147. 'pt-PT': /^\d{9}$/,
  1148. 'ro-RO': /^\d{13}$/,
  1149. 'sk-SK': /^\d{6}\/{0,1}\d{3,4}$/,
  1150. 'sl-SI': /^[1-9]\d{7}$/,
  1151. 'sv-SE': /^(\d{6}[-+]{0,1}\d{4}|(18|19|20)\d{6}[-+]{0,1}\d{4})$/
  1152. }; // taxIdFormat locale aliases
  1153. taxIdFormat['lb-LU'] = taxIdFormat['fr-LU'];
  1154. taxIdFormat['lt-LT'] = taxIdFormat['et-EE'];
  1155. taxIdFormat['nl-BE'] = taxIdFormat['fr-BE'];
  1156. taxIdFormat['fr-CA'] = taxIdFormat['en-CA']; // Algorithmic tax id check functions for various locales
  1157. var taxIdCheck = {
  1158. 'bg-BG': bgBgCheck,
  1159. 'cs-CZ': csCzCheck,
  1160. 'de-AT': deAtCheck,
  1161. 'de-DE': deDeCheck,
  1162. 'dk-DK': dkDkCheck,
  1163. 'el-CY': elCyCheck,
  1164. 'el-GR': elGrCheck,
  1165. 'en-CA': isCanadianSIN,
  1166. 'en-IE': enIeCheck,
  1167. 'en-US': enUsCheck,
  1168. 'es-ES': esEsCheck,
  1169. 'et-EE': etEeCheck,
  1170. 'fi-FI': fiFiCheck,
  1171. 'fr-BE': frBeCheck,
  1172. 'fr-FR': frFrCheck,
  1173. 'fr-LU': frLuCheck,
  1174. 'hr-HR': hrHrCheck,
  1175. 'hu-HU': huHuCheck,
  1176. 'it-IT': itItCheck,
  1177. 'lv-LV': lvLvCheck,
  1178. 'mt-MT': mtMtCheck,
  1179. 'nl-NL': nlNlCheck,
  1180. 'pl-PL': plPlCheck,
  1181. 'pt-BR': ptBrCheck,
  1182. 'pt-PT': ptPtCheck,
  1183. 'ro-RO': roRoCheck,
  1184. 'sk-SK': skSkCheck,
  1185. 'sl-SI': slSiCheck,
  1186. 'sv-SE': svSeCheck
  1187. }; // taxIdCheck locale aliases
  1188. taxIdCheck['lb-LU'] = taxIdCheck['fr-LU'];
  1189. taxIdCheck['lt-LT'] = taxIdCheck['et-EE'];
  1190. taxIdCheck['nl-BE'] = taxIdCheck['fr-BE'];
  1191. taxIdCheck['fr-CA'] = taxIdCheck['en-CA']; // Regexes for locales where characters should be omitted before checking format
  1192. var allsymbols = /[-\\\/!@#$%\^&\*\(\)\+\=\[\]]+/g;
  1193. var sanitizeRegexes = {
  1194. 'de-AT': allsymbols,
  1195. 'de-DE': /[\/\\]/g,
  1196. 'fr-BE': allsymbols
  1197. }; // sanitizeRegexes locale aliases
  1198. sanitizeRegexes['nl-BE'] = sanitizeRegexes['fr-BE'];
  1199. /*
  1200. * Validator function
  1201. * Return true if the passed string is a valid tax identification number
  1202. * for the specified locale.
  1203. * Throw an error exception if the locale is not supported.
  1204. */
  1205. function isTaxID(str) {
  1206. var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
  1207. (0, _assertString.default)(str); // Copy TIN to avoid replacement if sanitized
  1208. var strcopy = str.slice(0);
  1209. if (locale in taxIdFormat) {
  1210. if (locale in sanitizeRegexes) {
  1211. strcopy = strcopy.replace(sanitizeRegexes[locale], '');
  1212. }
  1213. if (!taxIdFormat[locale].test(strcopy)) {
  1214. return false;
  1215. }
  1216. if (locale in taxIdCheck) {
  1217. return taxIdCheck[locale](strcopy);
  1218. } // Fallthrough; not all locales have algorithmic checks
  1219. return true;
  1220. }
  1221. throw new Error("Invalid locale '".concat(locale, "'"));
  1222. }
  1223. module.exports = exports.default;
  1224. module.exports.default = exports.default;