id.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. (function($) {
  2. $.fn.bootstrapValidator.i18n.id = $.extend($.fn.bootstrapValidator.i18n.id || {}, {
  3. 'default': 'Please enter a valid identification number',
  4. countryNotSupported: 'The country code %s is not supported',
  5. country: 'Please enter a valid %s identification number',
  6. countries: {
  7. BA: 'Bosnia and Herzegovina',
  8. BG: 'Bulgarian',
  9. BR: 'Brazilian',
  10. CH: 'Swiss',
  11. CL: 'Chilean',
  12. CZ: 'Czech',
  13. DK: 'Danish',
  14. EE: 'Estonian',
  15. ES: 'Spanish',
  16. FI: 'Finnish',
  17. HR: 'Croatian',
  18. IE: 'Irish',
  19. IS: 'Iceland',
  20. LT: 'Lithuanian',
  21. LV: 'Latvian',
  22. ME: 'Montenegro',
  23. MK: 'Macedonian',
  24. NL: 'Dutch',
  25. RO: 'Romanian',
  26. RS: 'Serbian',
  27. SE: 'Swedish',
  28. SI: 'Slovenian',
  29. SK: 'Slovak',
  30. SM: 'San Marino',
  31. ZA: 'South African'
  32. },
  33. getMessage: function(options) {
  34. if (options.country) {
  35. var country = options.country.toLowerCase(),
  36. method = ['_', country].join('');
  37. if ($.fn.bootstrapValidator.validators.id[method] == undefined) {
  38. return $.fn.bootstrapValidator.helpers.format(this.countryNotSupported, country);
  39. }
  40. country = country.toUpperCase();
  41. if (this.countries[country]) {
  42. return $.fn.bootstrapValidator.helpers.format(this.country, this.countries[country]);
  43. }
  44. }
  45. return this['default'];
  46. }
  47. });
  48. $.fn.bootstrapValidator.validators.id = {
  49. html5Attributes: {
  50. message: 'message',
  51. country: 'country'
  52. },
  53. /**
  54. * Validate identification number in different countries
  55. *
  56. * @see http://en.wikipedia.org/wiki/National_identification_number
  57. * @param {BootstrapValidator} validator The validator plugin instance
  58. * @param {jQuery} $field Field element
  59. * @param {Object} options Consist of key:
  60. * - message: The invalid message
  61. * - country: The ISO 3166-1 country code
  62. * @returns {Boolean}
  63. */
  64. validate: function(validator, $field, options) {
  65. var value = $field.val();
  66. if (value == '') {
  67. return true;
  68. }
  69. var country = options.country || value.substr(0, 2),
  70. method = ['_', country.toLowerCase()].join('');
  71. if (this[method] && 'function' == typeof this[method]) {
  72. return this[method](value);
  73. }
  74. return false;
  75. },
  76. /**
  77. * Validate Unique Master Citizen Number which uses in
  78. * - Bosnia and Herzegovina (country code: BA)
  79. * - Macedonia (MK)
  80. * - Montenegro (ME)
  81. * - Serbia (RS)
  82. * - Slovenia (SI)
  83. *
  84. * @see http://en.wikipedia.org/wiki/Unique_Master_Citizen_Number
  85. * @param {String} value The ID
  86. * @param {String} countryCode The ISO country code, can be BA, MK, ME, RS, SI
  87. * @returns {Boolean}
  88. */
  89. _validateJMBG: function(value, countryCode) {
  90. if (!/^\d{13}$/.test(value)) {
  91. return false;
  92. }
  93. var day = parseInt(value.substr(0, 2), 10),
  94. month = parseInt(value.substr(2, 2), 10),
  95. year = parseInt(value.substr(4, 3), 10),
  96. rr = parseInt(value.substr(7, 2), 10),
  97. k = parseInt(value.substr(12, 1), 10);
  98. // Validate date of birth
  99. // FIXME: Validate the year of birth
  100. if (day > 31 || month > 12) {
  101. return false;
  102. }
  103. // Validate checksum
  104. var sum = 0;
  105. for (var i = 0; i < 6; i++) {
  106. sum += (7 - i) * (parseInt(value.charAt(i)) + parseInt(value.charAt(i + 6)));
  107. }
  108. sum = 11 - sum % 11;
  109. if (sum == 10 || sum == 11) {
  110. sum = 0;
  111. }
  112. if (sum != k) {
  113. return false;
  114. }
  115. // Validate political region
  116. // rr is the political region of birth, which can be in ranges:
  117. // 10-19: Bosnia and Herzegovina
  118. // 20-29: Montenegro
  119. // 30-39: Croatia (not used anymore)
  120. // 41-49: Macedonia
  121. // 50-59: Slovenia (only 50 is used)
  122. // 70-79: Central Serbia
  123. // 80-89: Serbian province of Vojvodina
  124. // 90-99: Kosovo
  125. switch (countryCode.toUpperCase()) {
  126. case 'BA':
  127. return (10 <= rr && rr <= 19);
  128. case 'MK':
  129. return (41 <= rr && rr <= 49);
  130. case 'ME':
  131. return (20 <= rr && rr <= 29);
  132. case 'RS':
  133. return (70 <= rr && rr <= 99);
  134. case 'SI':
  135. return (50 <= rr && rr <= 59);
  136. default:
  137. return true;
  138. }
  139. },
  140. _ba: function(value) {
  141. return this._validateJMBG(value, 'BA');
  142. },
  143. _mk: function(value) {
  144. return this._validateJMBG(value, 'MK');
  145. },
  146. _me: function(value) {
  147. return this._validateJMBG(value, 'ME');
  148. },
  149. _rs: function(value) {
  150. return this._validateJMBG(value, 'RS');
  151. },
  152. /**
  153. * Examples: 0101006500006
  154. */
  155. _si: function(value) {
  156. return this._validateJMBG(value, 'SI');
  157. },
  158. /**
  159. * Validate Bulgarian national identification number (EGN)
  160. * Examples:
  161. * - Valid: 7523169263, 8032056031, 803205 603 1, 8001010008, 7501020018, 7552010005, 7542011030
  162. * - Invalid: 8019010008
  163. *
  164. * @see http://en.wikipedia.org/wiki/Uniform_civil_number
  165. * @param {String} value The ID
  166. * @returns {Boolean}
  167. */
  168. _bg: function(value) {
  169. if (!/^\d{10}$/.test(value) && !/^\d{6}\s\d{3}\s\d{1}$/.test(value)) {
  170. return false;
  171. }
  172. value = value.replace(/\s/g, '');
  173. // Check the birth date
  174. var year = parseInt(value.substr(0, 2), 10) + 1900,
  175. month = parseInt(value.substr(2, 2), 10),
  176. day = parseInt(value.substr(4, 2), 10);
  177. if (month > 40) {
  178. year += 100;
  179. month -= 40;
  180. } else if (month > 20) {
  181. year -= 100;
  182. month -= 20;
  183. }
  184. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  185. return false;
  186. }
  187. var sum = 0,
  188. weight = [2, 4, 8, 5, 10, 9, 7, 3, 6];
  189. for (var i = 0; i < 9; i++) {
  190. sum += parseInt(value.charAt(i)) * weight[i];
  191. }
  192. sum = (sum % 11) % 10;
  193. return (sum == value.substr(9, 1));
  194. },
  195. /**
  196. * Validate Brazilian national identification number (CPF)
  197. * Examples:
  198. * - Valid: 39053344705, 390.533.447-05, 111.444.777-35
  199. * - Invalid: 231.002.999-00
  200. *
  201. * @see http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
  202. * @param {String} value The ID
  203. * @returns {Boolean}
  204. */
  205. _br: function(value) {
  206. if (/^1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}|0{11}$/.test(value)) {
  207. return false;
  208. }
  209. if (!/^\d{11}$/.test(value) && !/^\d{3}\.\d{3}\.\d{3}-\d{2}$/.test(value)) {
  210. return false;
  211. }
  212. value = value.replace(/\./g, '').replace(/-/g, '');
  213. var d1 = 0;
  214. for (var i = 0; i < 9; i++) {
  215. d1 += (10 - i) * parseInt(value.charAt(i));
  216. }
  217. d1 = 11 - d1 % 11;
  218. if (d1 == 10 || d1 == 11) {
  219. d1 = 0;
  220. }
  221. if (d1 != value.charAt(9)) {
  222. return false;
  223. }
  224. var d2 = 0;
  225. for (i = 0; i < 10; i++) {
  226. d2 += (11 - i) * parseInt(value.charAt(i));
  227. }
  228. d2 = 11 - d2 % 11;
  229. if (d2 == 10 || d2 == 11) {
  230. d2 = 0;
  231. }
  232. return (d2 == value.charAt(10));
  233. },
  234. /**
  235. * Validate Swiss Social Security Number (AHV-Nr/No AVS)
  236. * Examples:
  237. * - Valid: 756.1234.5678.95, 7561234567895
  238. *
  239. * @see http://en.wikipedia.org/wiki/National_identification_number#Switzerland
  240. * @see http://www.bsv.admin.ch/themen/ahv/00011/02185/index.html?lang=de
  241. * @param {String} value The ID
  242. * @returns {Boolean}
  243. */
  244. _ch: function(value) {
  245. if (!/^756[\.]{0,1}[0-9]{4}[\.]{0,1}[0-9]{4}[\.]{0,1}[0-9]{2}$/.test(value)) {
  246. return false;
  247. }
  248. value = value.replace(/\D/g, '').substr(3);
  249. var length = value.length,
  250. sum = 0,
  251. weight = (length == 8) ? [3, 1] : [1, 3];
  252. for (var i = 0; i < length - 1; i++) {
  253. sum += parseInt(value.charAt(i)) * weight[i % 2];
  254. }
  255. sum = 10 - sum % 10;
  256. return (sum == value.charAt(length - 1));
  257. },
  258. /**
  259. * Validate Chilean national identification number (RUN/RUT)
  260. * Examples:
  261. * - Valid: 76086428-5, 22060449-7, 12531909-2
  262. *
  263. * @see http://en.wikipedia.org/wiki/National_identification_number#Chile
  264. * @see https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html for samples
  265. * @param {String} value The ID
  266. * @returns {Boolean}
  267. */
  268. _cl: function(value) {
  269. if (!/^\d{7,8}[-]{0,1}[0-9K]$/.test(value)) {
  270. return false;
  271. }
  272. value = value.replace(/\D/g, '');
  273. while (value.length < 9) {
  274. value = '0' + value;
  275. }
  276. var sum = 0,
  277. weight = [3, 2, 7, 6, 5, 4, 3, 2];
  278. for (var i = 0; i < 8; i++) {
  279. sum += parseInt(value.charAt(i)) * weight[i];
  280. }
  281. sum = 11 - sum % 11;
  282. if (sum == 11) {
  283. sum = 0;
  284. } else if (sum == 10) {
  285. sum = 'K';
  286. }
  287. return sum == value.charAt(8);
  288. },
  289. /**
  290. * Validate Czech national identification number (RC)
  291. * Examples:
  292. * - Valid: 7103192745, 991231123
  293. * - Invalid: 1103492745, 590312123
  294. *
  295. * @param {String} value The ID
  296. * @returns {Boolean}
  297. */
  298. _cz: function(value) {
  299. if (!/^\d{9,10}$/.test(value)) {
  300. return false;
  301. }
  302. var year = 1900 + parseInt(value.substr(0, 2)),
  303. month = parseInt(value.substr(2, 2)) % 50 % 20,
  304. day = parseInt(value.substr(4, 2));
  305. if (value.length == 9) {
  306. if (year >= 1980) {
  307. year -= 100;
  308. }
  309. if (year > 1953) {
  310. return false;
  311. }
  312. } else if (year < 1954) {
  313. year += 100;
  314. }
  315. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  316. return false;
  317. }
  318. // Check that the birth date is not in the future
  319. if (value.length == 10) {
  320. var check = parseInt(value.substr(0, 9), 10) % 11;
  321. if (year < 1985) {
  322. check = check % 10;
  323. }
  324. return (check == value.substr(9, 1));
  325. }
  326. return true;
  327. },
  328. /**
  329. * Validate Danish Personal Identification number (CPR)
  330. * Examples:
  331. * - Valid: 2110625629, 211062-5629
  332. * - Invalid: 511062-5629
  333. *
  334. * @see https://en.wikipedia.org/wiki/Personal_identification_number_(Denmark)
  335. * @param {String} value The ID
  336. * @returns {Boolean}
  337. */
  338. _dk: function(value) {
  339. if (!/^[0-9]{6}[-]{0,1}[0-9]{4}$/.test(value)) {
  340. return false;
  341. }
  342. value = value.replace(/-/g, '');
  343. var day = parseInt(value.substr(0, 2), 10),
  344. month = parseInt(value.substr(2, 2), 10),
  345. year = parseInt(value.substr(4, 2), 10);
  346. switch (true) {
  347. case ('5678'.indexOf(value.charAt(6)) != -1 && year >= 58):
  348. year += 1800;
  349. break;
  350. case ('0123'.indexOf(value.charAt(6)) != -1):
  351. case ('49'.indexOf(value.charAt(6)) != -1 && year >= 37):
  352. year += 1900;
  353. break;
  354. default:
  355. year += 2000;
  356. break;
  357. }
  358. return $.fn.bootstrapValidator.helpers.date(year, month, day);
  359. },
  360. /**
  361. * Validate Estonian Personal Identification Code (isikukood)
  362. * Examples:
  363. * - Valid: 37605030299
  364. *
  365. * @see http://et.wikipedia.org/wiki/Isikukood
  366. * @param {String} value The ID
  367. * @returns {Boolean}
  368. */
  369. _ee: function(value) {
  370. // Use the same format as Lithuanian Personal Code
  371. return this._lt(value);
  372. },
  373. /**
  374. * Validate Spanish personal identity code (DNI)
  375. * Support i) DNI (for Spanish citizens) and ii) NIE (for foreign people)
  376. *
  377. * Examples:
  378. * - Valid: i) 54362315K, 54362315-K; ii) X2482300W, X-2482300W, X-2482300-W
  379. * - Invalid: i) 54362315Z; ii) X-2482300A
  380. *
  381. * @see https://en.wikipedia.org/wiki/National_identification_number#Spain
  382. * @param {String} value The ID
  383. * @returns {Boolean}
  384. */
  385. _es: function(value) {
  386. if (!/^[0-9A-Z]{8}[-]{0,1}[0-9A-Z]$/.test(value) // DNI
  387. && !/^[XYZ][-]{0,1}[0-9]{7}[-]{0,1}[0-9A-Z]$/.test(value)) { // NIE
  388. return false;
  389. }
  390. value = value.replace(/-/g, '');
  391. var index = 'XYZ'.indexOf(value.charAt(0));
  392. if (index != -1) {
  393. // It is NIE number
  394. value = index + value.substr(1) + '';
  395. }
  396. var check = parseInt(value.substr(0, 8), 10);
  397. check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
  398. return (check == value.substr(8, 1));
  399. },
  400. /**
  401. * Validate Finnish Personal Identity Code (HETU)
  402. * Examples:
  403. * - Valid: 311280-888Y, 131052-308T
  404. * - Invalid: 131052-308U, 310252-308Y
  405. *
  406. * @param {String} value The ID
  407. * @returns {Boolean}
  408. */
  409. _fi: function(value) {
  410. if (!/^[0-9]{6}[-+A][0-9]{3}[0-9ABCDEFHJKLMNPRSTUVWXY]$/.test(value)) {
  411. return false;
  412. }
  413. var day = parseInt(value.substr(0, 2), 10),
  414. month = parseInt(value.substr(2, 2), 10),
  415. year = parseInt(value.substr(4, 2), 10),
  416. centuries = {
  417. '+': 1800,
  418. '-': 1900,
  419. 'A': 2000
  420. };
  421. year = centuries[value.charAt(6)] + year;
  422. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  423. return false;
  424. }
  425. var individual = parseInt(value.substr(7, 3));
  426. if (individual < 2) {
  427. return false;
  428. }
  429. var n = value.substr(0, 6) + value.substr(7, 3) + '';
  430. n = parseInt(n);
  431. return '0123456789ABCDEFHJKLMNPRSTUVWXY'.charAt(n % 31) == value.charAt(10);
  432. },
  433. /**
  434. * Validate Croatian personal identification number (OIB)
  435. * Examples:
  436. * - Valid: 33392005961
  437. * - Invalid: 33392005962
  438. *
  439. * @param {String} value The ID
  440. * @returns {Boolean}
  441. */
  442. _hr: function(value) {
  443. if (!/^[0-9]{11}$/.test(value)) {
  444. return false;
  445. }
  446. return $.fn.bootstrapValidator.helpers.mod_11_10(value);
  447. },
  448. /**
  449. * Validate Irish Personal Public Service Number (PPS)
  450. * Examples:
  451. * - Valid: 6433435F, 6433435FT, 6433435FW, 6433435OA, 6433435IH, 1234567TW, 1234567FA
  452. * - Invalid: 6433435E, 6433435VH
  453. *
  454. * @see https://en.wikipedia.org/wiki/Personal_Public_Service_Number
  455. * @param {String} value The ID
  456. * @returns {Boolean}
  457. */
  458. _ie: function(value) {
  459. if (!/^\d{7}[A-W][AHWTX]?$/.test(value)) {
  460. return false;
  461. }
  462. var getCheckDigit = function(value) {
  463. while (value.length < 7) {
  464. value = '0' + value;
  465. }
  466. var alphabet = 'WABCDEFGHIJKLMNOPQRSTUV',
  467. sum = 0;
  468. for (var i = 0; i < 7; i++) {
  469. sum += parseInt(value.charAt(i)) * (8 - i);
  470. }
  471. sum += 9 * alphabet.indexOf(value.substr(7));
  472. return alphabet[sum % 23];
  473. };
  474. // 2013 format
  475. if (value.length == 9 && ('A' == value.charAt(8) || 'H' == value.charAt(8))) {
  476. return value.charAt(7) == getCheckDigit(value.substr(0, 7) + value.substr(8) + '');
  477. }
  478. // The old format
  479. else {
  480. return value.charAt(7) == getCheckDigit(value.substr(0, 7));
  481. }
  482. },
  483. /**
  484. * Validate Iceland national identification number (Kennitala)
  485. * Examples:
  486. * - Valid: 120174-3399, 1201743399, 0902862349
  487. *
  488. * @see http://en.wikipedia.org/wiki/Kennitala
  489. * @param {String} value The ID
  490. * @returns {Boolean}
  491. */
  492. _is: function(value) {
  493. if (!/^[0-9]{6}[-]{0,1}[0-9]{4}$/.test(value)) {
  494. return false;
  495. }
  496. value = value.replace(/-/g, '');
  497. var day = parseInt(value.substr(0, 2), 10),
  498. month = parseInt(value.substr(2, 2), 10),
  499. year = parseInt(value.substr(4, 2), 10),
  500. century = parseInt(value.charAt(9));
  501. year = (century == 9) ? (1900 + year) : ((20 + century) * 100 + year);
  502. if (!$.fn.bootstrapValidator.helpers.date(year, month, day, true)) {
  503. return false;
  504. }
  505. // Validate the check digit
  506. var sum = 0,
  507. weight = [3, 2, 7, 6, 5, 4, 3, 2];
  508. for (var i = 0; i < 8; i++) {
  509. sum += parseInt(value.charAt(i)) * weight[i];
  510. }
  511. sum = 11 - sum % 11;
  512. return (sum == value.charAt(8));
  513. },
  514. /**
  515. * Validate Lithuanian Personal Code (Asmens kodas)
  516. * Examples:
  517. * - Valid: 38703181745
  518. * - Invalid: 38703181746, 78703181745, 38703421745
  519. *
  520. * @see http://en.wikipedia.org/wiki/National_identification_number#Lithuania
  521. * @see http://www.adomas.org/midi2007/pcode.html
  522. * @param {String} value The ID
  523. * @returns {Boolean}
  524. */
  525. _lt: function(value) {
  526. if (!/^[0-9]{11}$/.test(value)) {
  527. return false;
  528. }
  529. var gender = parseInt(value.charAt(0)),
  530. year = parseInt(value.substr(1, 2), 10),
  531. month = parseInt(value.substr(3, 2), 10),
  532. day = parseInt(value.substr(5, 2), 10),
  533. century = (gender % 2 == 0) ? (17 + gender / 2) : (17 + (gender + 1) / 2);
  534. year = century * 100 + year;
  535. if (!$.fn.bootstrapValidator.helpers.date(year, month, day, true)) {
  536. return false;
  537. }
  538. // Validate the check digit
  539. var sum = 0,
  540. weight = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1];
  541. for (var i = 0; i < 10; i++) {
  542. sum += parseInt(value.charAt(i)) * weight[i];
  543. }
  544. sum = sum % 11;
  545. if (sum != 10) {
  546. return sum == value.charAt(10);
  547. }
  548. // Re-calculate the check digit
  549. sum = 0;
  550. weight = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3];
  551. for (i = 0; i < 10; i++) {
  552. sum += parseInt(value.charAt(i)) * weight[i];
  553. }
  554. sum = sum % 11;
  555. if (sum == 10) {
  556. sum = 0;
  557. }
  558. return (sum == value.charAt(10));
  559. },
  560. /**
  561. * Validate Latvian Personal Code (Personas kods)
  562. * Examples:
  563. * - Valid: 161175-19997, 16117519997
  564. * - Invalid: 161375-19997
  565. *
  566. * @see http://laacz.lv/2006/11/25/pk-parbaudes-algoritms/
  567. * @param {String} value The ID
  568. * @returns {Boolean}
  569. */
  570. _lv: function(value) {
  571. if (!/^[0-9]{6}[-]{0,1}[0-9]{5}$/.test(value)) {
  572. return false;
  573. }
  574. value = value.replace(/\D/g, '');
  575. // Check birth date
  576. var day = parseInt(value.substr(0, 2)),
  577. month = parseInt(value.substr(2, 2)),
  578. year = parseInt(value.substr(4, 2));
  579. year = year + 1800 + parseInt(value.charAt(6)) * 100;
  580. if (!$.fn.bootstrapValidator.helpers.date(year, month, day, true)) {
  581. return false;
  582. }
  583. // Check personal code
  584. var sum = 0,
  585. weight = [10, 5, 8, 4, 2, 1, 6, 3, 7, 9];
  586. for (var i = 0; i < 10; i++) {
  587. sum += parseInt(value.charAt(i)) * weight[i];
  588. }
  589. sum = (sum + 1) % 11 % 10;
  590. return (sum == value.charAt(10));
  591. },
  592. /**
  593. * Validate Dutch national identification number (BSN)
  594. * Examples:
  595. * - Valid: 111222333, 941331490, 9413.31.490
  596. * - Invalid: 111252333
  597. *
  598. * @see https://nl.wikipedia.org/wiki/Burgerservicenummer
  599. * @param {String} value The ID
  600. * @returns {Boolean}
  601. */
  602. _nl: function(value) {
  603. while (value.length < 9) {
  604. value = '0' + value;
  605. }
  606. if (!/^[0-9]{4}[.]{0,1}[0-9]{2}[.]{0,1}[0-9]{3}$/.test(value)) {
  607. return false;
  608. }
  609. value = value.replace(/\./g, '');
  610. if (parseInt(value, 10) == 0) {
  611. return false;
  612. }
  613. var sum = 0,
  614. length = value.length;
  615. for (var i = 0; i < length - 1; i++) {
  616. sum += (9 - i) * parseInt(value.charAt(i));
  617. }
  618. sum = sum % 11;
  619. if (sum == 10) {
  620. sum = 0;
  621. }
  622. return (sum == value.charAt(length - 1));
  623. },
  624. /**
  625. * Validate Romanian numerical personal code (CNP)
  626. * Examples:
  627. * - Valid: 1630615123457, 1800101221144
  628. * - Invalid: 8800101221144, 1632215123457, 1630615123458
  629. *
  630. * @see http://en.wikipedia.org/wiki/National_identification_number#Romania
  631. * @param {String} value The ID
  632. * @returns {Boolean}
  633. */
  634. _ro: function(value) {
  635. if (!/^[0-9]{13}$/.test(value)) {
  636. return false;
  637. }
  638. var gender = parseInt(value.charAt(0));
  639. if (gender == 0 || gender == 7 || gender == 8) {
  640. return false;
  641. }
  642. // Determine the date of birth
  643. var year = parseInt(value.substr(1, 2), 10),
  644. month = parseInt(value.substr(3, 2), 10),
  645. day = parseInt(value.substr(5, 2), 10),
  646. // The year of date is determined base on the gender
  647. centuries = {
  648. '1': 1900, // Male born between 1900 and 1999
  649. '2': 1900, // Female born between 1900 and 1999
  650. '3': 1800, // Male born between 1800 and 1899
  651. '4': 1800, // Female born between 1800 and 1899
  652. '5': 2000, // Male born after 2000
  653. '6': 2000 // Female born after 2000
  654. };
  655. if (day > 31 && month > 12) {
  656. return false;
  657. }
  658. if (gender != 9) {
  659. year = centuries[gender + ''] + year;
  660. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  661. return false;
  662. }
  663. }
  664. // Validate the check digit
  665. var sum = 0,
  666. weight = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9],
  667. length = value.length;
  668. for (var i = 0; i < length - 1; i++) {
  669. sum += parseInt(value.charAt(i)) * weight[i];
  670. }
  671. sum = sum % 11;
  672. if (sum == 10) {
  673. sum = 1;
  674. }
  675. return (sum == value.charAt(length - 1));
  676. },
  677. /**
  678. * Validate Swedish personal identity number (personnummer)
  679. * Examples:
  680. * - Valid: 8112289874, 811228-9874, 811228+9874
  681. * - Invalid: 811228-9873
  682. *
  683. * @see http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)
  684. * @param {String} value The ID
  685. * @returns {Boolean}
  686. */
  687. _se: function(value) {
  688. if (!/^[0-9]{10}$/.test(value) && !/^[0-9]{6}[-|+][0-9]{4}$/.test(value)) {
  689. return false;
  690. }
  691. value = value.replace(/[^0-9]/g, '');
  692. var year = parseInt(value.substr(0, 2)) + 1900,
  693. month = parseInt(value.substr(2, 2)),
  694. day = parseInt(value.substr(4, 2));
  695. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  696. return false;
  697. }
  698. // Validate the last check digit
  699. return $.fn.bootstrapValidator.helpers.luhn(value);
  700. },
  701. /**
  702. * Validate Slovak national identifier number (RC)
  703. * Examples:
  704. * - Valid: 7103192745, 991231123
  705. * - Invalid: 7103192746, 1103492745
  706. *
  707. * @param {String} value The ID
  708. * @returns {Boolean}
  709. */
  710. _sk: function(value) {
  711. // Slovakia uses the same format as Czech Republic
  712. return this._cz(value);
  713. },
  714. /**
  715. * Validate San Marino citizen number
  716. *
  717. * @see http://en.wikipedia.org/wiki/National_identification_number#San_Marino
  718. * @param {String} value The ID
  719. * @returns {Boolean}
  720. */
  721. _sm: function(value) {
  722. return /^\d{5}$/.test(value);
  723. },
  724. /**
  725. * Validate South African ID
  726. * Example:
  727. * - Valid: 8001015009087
  728. * - Invalid: 8001015009287, 8001015009086
  729. *
  730. * @see http://en.wikipedia.org/wiki/National_identification_number#South_Africa
  731. * @param {String} value The ID
  732. * @returns {Boolean}
  733. */
  734. _za: function(value) {
  735. if (!/^[0-9]{10}[0|1][8|9][0-9]$/.test(value)) {
  736. return false;
  737. }
  738. var year = parseInt(value.substr(0, 2)),
  739. currentYear = new Date().getFullYear() % 100,
  740. month = parseInt(value.substr(2, 2)),
  741. day = parseInt(value.substr(4, 2));
  742. year = (year >= currentYear) ? (year + 1900) : (year + 2000);
  743. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  744. return false;
  745. }
  746. // Validate the last check digit
  747. return $.fn.bootstrapValidator.helpers.luhn(value);
  748. }
  749. };
  750. }(window.jQuery));