id.js 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  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 identification number in %s',
  6. countries: {
  7. BA: 'Bosnia and Herzegovina',
  8. BG: 'Bulgaria',
  9. BR: 'Brazil',
  10. CH: 'Switzerland',
  11. CL: 'Chile',
  12. CN: 'China',
  13. CZ: 'Czech',
  14. DK: 'Denmark',
  15. EE: 'Estonia',
  16. ES: 'Spain',
  17. FI: 'Finland',
  18. HR: 'Croatia',
  19. IE: 'Ireland',
  20. IS: 'Iceland',
  21. LT: 'Lithuania',
  22. LV: 'Latvia',
  23. ME: 'Montenegro',
  24. MK: 'Macedonia',
  25. NL: 'Netherlands',
  26. RO: 'Romania',
  27. RS: 'Serbia',
  28. SE: 'Sweden',
  29. SI: 'Slovenia',
  30. SK: 'Slovakia',
  31. SM: 'San Marino',
  32. ZA: 'South Africa'
  33. }
  34. });
  35. $.fn.bootstrapValidator.validators.id = {
  36. html5Attributes: {
  37. message: 'message',
  38. country: 'country'
  39. },
  40. // Supported country codes
  41. COUNTRY_CODES: [
  42. 'BA', 'BG', 'BR', 'CH', 'CL', 'CN', 'CZ', 'DK', 'EE', 'ES',
  43. 'FI', 'HR', 'IE', 'IS', 'LT', 'LV', 'ME', 'MK', 'NL', 'RO',
  44. 'RS', 'SE', 'SI', 'SK', 'SM', 'ZA'
  45. ],
  46. /**
  47. * Validate identification number in different countries
  48. *
  49. * @see http://en.wikipedia.org/wiki/National_identification_number
  50. * @param {BootstrapValidator} validator The validator plugin instance
  51. * @param {jQuery} $field Field element
  52. * @param {Object} options Consist of key:
  53. * - message: The invalid message
  54. * - country: The ISO 3166-1 country code. It can be
  55. * - One of country code defined in COUNTRY_CODES
  56. * - Name of field which its value defines the country code
  57. * - Name of callback function that returns the country code
  58. * - A callback function that returns the country code
  59. * @returns {Boolean|Object}
  60. */
  61. validate: function(validator, $field, options) {
  62. var value = $field.val();
  63. if (value === '') {
  64. return true;
  65. }
  66. var country = options.country;
  67. if (!country) {
  68. country = value.substr(0, 2);
  69. } else if (typeof country !== 'string' || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) {
  70. // Determine the country code
  71. country = validator.getDynamicOption($field, country);
  72. }
  73. if ($.inArray(country, this.COUNTRY_CODES) === -1) {
  74. return { valid: false, message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.id.countryNotSupported, country) };
  75. }
  76. var method = ['_', country.toLowerCase()].join('');
  77. return this[method](value)
  78. ? true
  79. : {
  80. valid: false,
  81. message: $.fn.bootstrapValidator.helpers.format(options.message || $.fn.bootstrapValidator.i18n.id.country, $.fn.bootstrapValidator.i18n.id.countries[country.toUpperCase()])
  82. };
  83. },
  84. /**
  85. * Validate Unique Master Citizen Number which uses in
  86. * - Bosnia and Herzegovina (country code: BA)
  87. * - Macedonia (MK)
  88. * - Montenegro (ME)
  89. * - Serbia (RS)
  90. * - Slovenia (SI)
  91. *
  92. * @see http://en.wikipedia.org/wiki/Unique_Master_Citizen_Number
  93. * @param {String} value The ID
  94. * @param {String} countryCode The ISO country code, can be BA, MK, ME, RS, SI
  95. * @returns {Boolean}
  96. */
  97. _validateJMBG: function(value, countryCode) {
  98. if (!/^\d{13}$/.test(value)) {
  99. return false;
  100. }
  101. var day = parseInt(value.substr(0, 2), 10),
  102. month = parseInt(value.substr(2, 2), 10),
  103. year = parseInt(value.substr(4, 3), 10),
  104. rr = parseInt(value.substr(7, 2), 10),
  105. k = parseInt(value.substr(12, 1), 10);
  106. // Validate date of birth
  107. // FIXME: Validate the year of birth
  108. if (day > 31 || month > 12) {
  109. return false;
  110. }
  111. // Validate checksum
  112. var sum = 0;
  113. for (var i = 0; i < 6; i++) {
  114. sum += (7 - i) * (parseInt(value.charAt(i), 10) + parseInt(value.charAt(i + 6), 10));
  115. }
  116. sum = 11 - sum % 11;
  117. if (sum === 10 || sum === 11) {
  118. sum = 0;
  119. }
  120. if (sum !== k) {
  121. return false;
  122. }
  123. // Validate political region
  124. // rr is the political region of birth, which can be in ranges:
  125. // 10-19: Bosnia and Herzegovina
  126. // 20-29: Montenegro
  127. // 30-39: Croatia (not used anymore)
  128. // 41-49: Macedonia
  129. // 50-59: Slovenia (only 50 is used)
  130. // 70-79: Central Serbia
  131. // 80-89: Serbian province of Vojvodina
  132. // 90-99: Kosovo
  133. switch (countryCode.toUpperCase()) {
  134. case 'BA':
  135. return (10 <= rr && rr <= 19);
  136. case 'MK':
  137. return (41 <= rr && rr <= 49);
  138. case 'ME':
  139. return (20 <= rr && rr <= 29);
  140. case 'RS':
  141. return (70 <= rr && rr <= 99);
  142. case 'SI':
  143. return (50 <= rr && rr <= 59);
  144. default:
  145. return true;
  146. }
  147. },
  148. _ba: function(value) {
  149. return this._validateJMBG(value, 'BA');
  150. },
  151. _mk: function(value) {
  152. return this._validateJMBG(value, 'MK');
  153. },
  154. _me: function(value) {
  155. return this._validateJMBG(value, 'ME');
  156. },
  157. _rs: function(value) {
  158. return this._validateJMBG(value, 'RS');
  159. },
  160. /**
  161. * Examples: 0101006500006
  162. */
  163. _si: function(value) {
  164. return this._validateJMBG(value, 'SI');
  165. },
  166. /**
  167. * Validate Bulgarian national identification number (EGN)
  168. * Examples:
  169. * - Valid: 7523169263, 8032056031, 803205 603 1, 8001010008, 7501020018, 7552010005, 7542011030
  170. * - Invalid: 8019010008
  171. *
  172. * @see http://en.wikipedia.org/wiki/Uniform_civil_number
  173. * @param {String} value The ID
  174. * @returns {Boolean}
  175. */
  176. _bg: function(value) {
  177. if (!/^\d{10}$/.test(value) && !/^\d{6}\s\d{3}\s\d{1}$/.test(value)) {
  178. return false;
  179. }
  180. value = value.replace(/\s/g, '');
  181. // Check the birth date
  182. var year = parseInt(value.substr(0, 2), 10) + 1900,
  183. month = parseInt(value.substr(2, 2), 10),
  184. day = parseInt(value.substr(4, 2), 10);
  185. if (month > 40) {
  186. year += 100;
  187. month -= 40;
  188. } else if (month > 20) {
  189. year -= 100;
  190. month -= 20;
  191. }
  192. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  193. return false;
  194. }
  195. var sum = 0,
  196. weight = [2, 4, 8, 5, 10, 9, 7, 3, 6];
  197. for (var i = 0; i < 9; i++) {
  198. sum += parseInt(value.charAt(i), 10) * weight[i];
  199. }
  200. sum = (sum % 11) % 10;
  201. return (sum + '' === value.substr(9, 1));
  202. },
  203. /**
  204. * Validate Brazilian national identification number (CPF)
  205. * Examples:
  206. * - Valid: 39053344705, 390.533.447-05, 111.444.777-35
  207. * - Invalid: 231.002.999-00
  208. *
  209. * @see http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
  210. * @param {String} value The ID
  211. * @returns {Boolean}
  212. */
  213. _br: function(value) {
  214. if (/^1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}|0{11}$/.test(value)) {
  215. return false;
  216. }
  217. if (!/^\d{11}$/.test(value) && !/^\d{3}\.\d{3}\.\d{3}-\d{2}$/.test(value)) {
  218. return false;
  219. }
  220. value = value.replace(/\./g, '').replace(/-/g, '');
  221. var d1 = 0;
  222. for (var i = 0; i < 9; i++) {
  223. d1 += (10 - i) * parseInt(value.charAt(i), 10);
  224. }
  225. d1 = 11 - d1 % 11;
  226. if (d1 === 10 || d1 === 11) {
  227. d1 = 0;
  228. }
  229. if (d1 + '' !== value.charAt(9)) {
  230. return false;
  231. }
  232. var d2 = 0;
  233. for (i = 0; i < 10; i++) {
  234. d2 += (11 - i) * parseInt(value.charAt(i), 10);
  235. }
  236. d2 = 11 - d2 % 11;
  237. if (d2 === 10 || d2 === 11) {
  238. d2 = 0;
  239. }
  240. return (d2 + '' === value.charAt(10));
  241. },
  242. /**
  243. * Validate Swiss Social Security Number (AHV-Nr/No AVS)
  244. * Examples:
  245. * - Valid: 756.1234.5678.95, 7561234567895
  246. *
  247. * @see http://en.wikipedia.org/wiki/National_identification_number#Switzerland
  248. * @see http://www.bsv.admin.ch/themen/ahv/00011/02185/index.html?lang=de
  249. * @param {String} value The ID
  250. * @returns {Boolean}
  251. */
  252. _ch: function(value) {
  253. if (!/^756[\.]{0,1}[0-9]{4}[\.]{0,1}[0-9]{4}[\.]{0,1}[0-9]{2}$/.test(value)) {
  254. return false;
  255. }
  256. value = value.replace(/\D/g, '').substr(3);
  257. var length = value.length,
  258. sum = 0,
  259. weight = (length === 8) ? [3, 1] : [1, 3];
  260. for (var i = 0; i < length - 1; i++) {
  261. sum += parseInt(value.charAt(i), 10) * weight[i % 2];
  262. }
  263. sum = 10 - sum % 10;
  264. return (sum + '' === value.charAt(length - 1));
  265. },
  266. /**
  267. * Validate Chilean national identification number (RUN/RUT)
  268. * Examples:
  269. * - Valid: 76086428-5, 22060449-7, 12531909-2
  270. *
  271. * @see http://en.wikipedia.org/wiki/National_identification_number#Chile
  272. * @see https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html for samples
  273. * @param {String} value The ID
  274. * @returns {Boolean}
  275. */
  276. _cl: function(value) {
  277. if (!/^\d{7,8}[-]{0,1}[0-9K]$/i.test(value)) {
  278. return false;
  279. }
  280. value = value.replace(/\-/g, '');
  281. while (value.length < 9) {
  282. value = '0' + value;
  283. }
  284. var sum = 0,
  285. weight = [3, 2, 7, 6, 5, 4, 3, 2];
  286. for (var i = 0; i < 8; i++) {
  287. sum += parseInt(value.charAt(i), 10) * weight[i];
  288. }
  289. sum = 11 - sum % 11;
  290. if (sum === 11) {
  291. sum = 0;
  292. } else if (sum === 10) {
  293. sum = 'K';
  294. }
  295. return sum + '' === value.charAt(8).toUpperCase();
  296. },
  297. /**
  298. * Validate Chinese citizen identification number
  299. *
  300. * @see http://en.wikipedia.org/wiki/Resident_Identity_Card#Identity_card_number
  301. * @param {String} value The ID
  302. * @returns {Boolean}
  303. */
  304. _cn: function(value) {
  305. /**
  306. * Rules:
  307. * - For current 18-digit system (since 1st Oct 1999, defined by GB11643—1999 national
  308. * standard):
  309. * - Digit 0-5: Must be a valid administrative division code of China PR.
  310. * - Digit 6-13: Must be a valid YYYYMMDD date of birth. A future date is tolerated.
  311. * - Digit 14-16: Order code, any integer.
  312. * - Digit 17: An ISO 7064:1983, MOD 11-2 checksum.
  313. * Both upper/lower case of X are tolerated.
  314. * - For deprecated 15-digit system:
  315. * - Digit 0-5: Must be a valid administrative division code of China PR.
  316. * - Digit 6-11: Must be a valid YYMMDD date of birth, indicating the year of 19XX.
  317. * - Digit 12-14: Order code, any integer.
  318. * Lists of valid administrative division codes of China PR can be seen here:
  319. * <http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/>
  320. * Published and maintanced by National Bureau of Statistics of China PR.
  321. * NOTE: Current and deprecated codes MUST BOTH be considered valid - many Chinese
  322. * citizens born in once existed admistrative divisions!
  323. */
  324. // Basic format check (18 or 15 digits, considering X in checksum)
  325. value = value.trim();
  326. if (!/^\d{15}$/.test(value) && !/^\d{17}[\dXx]{1}$/.test(value)) { return false; }
  327. // Check China PR Administrative division code
  328. var china_admin_div_codes = {11:{0:[0],1:[[0,9],[11,17]],2:[0,[28,29]]},12:{0:[0
  329. ],1:[[0,16]],2:[0,21,23,25]},13:{0:[0],1:[[0,5],[7,8],21,[23,33],[81,85]],2:
  330. [[0,5],[7,9],[23,25],27,[29,30],81,83],3:[[0,4],[21,24]],4:[[0,4],6,21,[23,35],81],
  331. 5:[[0,3],[21,35],[81,82]],6:[[0,4],[21,38],[81,84]],7:[[0,3],[5,6],[21,33]],8:[[
  332. 0,4],[21,28]],9:[[0,3],[21,30],[81,84]],10:[[0,3],[22,26],28,[81,82]],11:[[0,2],[
  333. 21,28],[81,82]]},14:{0:[0],1:[[0,1],[5,10],[21,23],81],2:[[0,3],[11,12],[21,27]]
  334. ,3:[[0,3],11,[21,22]],4:[[0,2],11,21,[23,31],81],5:[[0,2],[21,22],[24,25],81],6:
  335. [[0,3],[21,24]],7:[[0,2],[21,29],81],8:[[0,2],[21,30],[81,82]],9:[[0,2],[21,32],81
  336. ],10:[[0,2],[21,34],[81,82]],11:[[0,2],[21,30],[81,82]],23:[[0,3],[22,23],[25,30],
  337. [32,33]]},15:{0:[0],1:[[0,5],[21,25]],2:[[0,7],[21,23]],3:[[0,4]],4:[[0,4],[
  338. 21,26],[28,30]],5:[[0,2],[21,26],81],6:[[0,2],[21,27]],7:[[0,3],[21,27],[81,85]],
  339. 8:[[0,2],[21,26]],9:[[0,2],[21,29],81],22:[[0,2],[21,24]],25:[[0,2],[22,31]],
  340. 26:[[0,2],[24,27],[29,32],34],28:[[0,1],[22,27]],29:[0,[21,23]]},21:{0:[0],1
  341. :[[0,6],[11,14],[22,24],81],2:[[0,4],[11,13],24,[81,83]],3:[[0,4],11,21,23,81],4:[
  342. [0,4],11,[21,23]],5:[[0,5],[21,22]],6:[[0,4],24,[81,82]],7:[[0,3],11,[26,27],[81,
  343. 82]],8:[[0,4],11,[81,82]],9:[[0,5],11,[21,22]],10:[[0,5],11,21,81],11:[[0,3],[21
  344. ,22]],12:[[0,2],4,21,[23,24],[81,82]],13:[[0,3],[21,22],24,[81,82]],14:[[0,4],[21,
  345. 22],81]},22:{0:[0],1:[[0,6],12,22,[81,83]],2:[[0,4],11,21,[81,84]],3:[[0,3],[
  346. 22,23],[81,82]],4:[[0,3],[21,22]],5:[[0,3],21,[23,24],[81,82]],6:[[0,2],[4,5],[21,
  347. 23],25,81],7:[[0,2],[21,24],81],8:[[0,2],[21,22],[81,82]],24:[[0,6],24,26]},23:{
  348. 0:[0],1:[[0,12],21,[23,29],[81,84]],2:[[0,8],21,[23,25],27,[29,31],81],3:[[0,7],
  349. 21,[81,82]],4:[[0,7],[21,22]],5:[[0,3],[5,6],[21,24]],6:[[0,6],[21,24]],7:[[0,16
  350. ],22,81],8:[[0,5],11,22,26,28,33,[81,82]],9:[[0,4],21],10:[[0,5],[24,25],81,[83,85
  351. ]],11:[[0,2],21,[23,24],[81,82]],12:[[0,2],[21,26],[81,83]],27:[[0,4],[21,23]]},
  352. 31:{0:[0],1:[[0,1],[3,10],[12,20]],2:[0,30]},32:{0:[0],1:[[0,7],11,[13,18]
  353. ,[24,25]],2:[[0,6],11,[81,82]],3:[[0,5],[11,12],[21,24],[81,82]],4:[[0,2],[4,5],[
  354. 11,12],[81,82]],5:[[0,9],[81,85]],6:[[0,2],[11,12],21,23,[81,84]],7:[[0,1],3,[5,6]
  355. ,[21,24]],8:[[0,4],11,26,[29,31]],9:[[0,3],[21,25],28,[81,82]],10:[[0,3],[11,12],
  356. 23,81,84,88],11:[[0,2],[11,12],[81,83]],12:[[0,4],[81,84]],13:[[0,2],11,[21,24]]},
  357. 33:{0:[0],1:[[0,6],[8,10],22,27,[82,83],85],2:[[0,1],[3,6],[11,12],[25,26],[81,
  358. 83]],3:[[0,4],22,24,[26,29],[81,82]],4:[[0,2],11,21,24,[81,83]],5:[[0,3],[21,23]],
  359. 6:[[0,2],21,24,[81,83]],7:[[0,3],23,[26,27],[81,84]],8:[[0,3],22,[24,25],81],9:[
  360. [0,3],[21,22]],10:[[0,4],[21,24],[81,82]],11:[[0,2],[21,27],81]},34:{0:[0],1:[
  361. [0,4],11,[21,24],81],2:[[0,4],[7,8],[21,23],25],3:[[0,4],11,[21,23]],4:[[0,6],21],
  362. 5:[[0,4],6,[21,23]],6:[[0,4],21],7:[[0,3],11,21],8:[[0,3],11,[22,28],81],10:[[
  363. 0,4],[21,24]],11:[[0,3],22,[24,26],[81,82]],12:[[0,4],[21,22],[25,26],82],13:[[0,2
  364. ],[21,24]],14:[[0,2],[21,24]],15:[[0,3],[21,25]],16:[[0,2],[21,23]],17:[[0,2],[
  365. 21,23]],18:[[0,2],[21,25],81]},35:{0:[0],1:[[0,5],11,[21,25],28,[81,82]],2:[[0
  366. ,6],[11,13]],3:[[0,5],22],4:[[0,3],21,[23,30],81],5:[[0,5],21,[24,27],[81,83]],6
  367. :[[0,3],[22,29],81],7:[[0,2],[21,25],[81,84]],8:[[0,2],[21,25],81],9:[[0,2],[21,26
  368. ],[81,82]]},36:{0:[0],1:[[0,5],11,[21,24]],2:[[0,3],22,81],3:[[0,2],13,[21,23]
  369. ],4:[[0,3],21,[23,30],[81,82]],5:[[0,2],21],6:[[0,2],22,81],7:[[0,2],[21,35],[81
  370. ,82]],8:[[0,3],[21,30],81],9:[[0,2],[21,26],[81,83]],10:[[0,2],[21,30]],11:[[0,2
  371. ],[21,30],81]},37:{0:[0],1:[[0,5],[12,13],[24,26],81],2:[[0,3],5,[11,14],[81,85]
  372. ],3:[[0,6],[21,23]],4:[[0,6],81],5:[[0,3],[21,23]],6:[[0,2],[11,13],34,[81,87]],
  373. 7:[[0,5],[24,25],[81,86]],8:[[0,2],11,[26,32],[81,83]],9:[[0,3],11,21,23,[82,83]],
  374. 10:[[0,2],[81,83]],11:[[0,3],[21,22]],12:[[0,3]],13:[[0,2],[11,12],[21,29]],14
  375. :[[0,2],[21,28],[81,82]],15:[[0,2],[21,26],81],16:[[0,2],[21,26]],17:[[0,2],[21,28
  376. ]]},41:{0:[0],1:[[0,6],8,22,[81,85]],2:[[0,5],11,[21,25]],3:[[0,7],11,[22,29],
  377. 81],4:[[0,4],11,[21,23],25,[81,82]],5:[[0,3],[5,6],[22,23],[26,27],81],6:[[0,3],11
  378. ,[21,22]],7:[[0,4],11,21,[24,28],[81,82]],8:[[0,4],11,[21,23],25,[81,83]],9:[[0,2]
  379. ,[22,23],[26,28]],10:[[0,2],[23,25],[81,82]],11:[[0,4],[21,23]],12:[[0,2],[21,22],
  380. 24,[81,82]],13:[[0,3],[21,30],81],14:[[0,3],[21,26],81],15:[[0,3],[21,28]],16:[[
  381. 0,2],[21,28],81],17:[[0,2],[21,29]],90:[[0,1]]},42:{0:[0],1:[[0,7],[11,17]],
  382. 2:[[0,5],22,81],3:[[0,3],[21,25],81],5:[[0,6],[25,29],[81,83]],6:[[0,2],[6,7],[
  383. 24,26],[82,84]],7:[[0,4]],8:[[0,2],4,[21,22],81],9:[[0,2],[21,23],[81,82],84],10
  384. :[[0,3],[22,24],81,83,87],11:[[0,2],[21,27],[81,82]],12:[[0,2],[21,24],81],13:[[0,
  385. 3],21,81],90:[0,[4,6],21],28:[[0,2],[22,23],[25,28]]},43:{0:[0],1:[[0,5],[11,
  386. 12],[21,22],24,81],2:[[0,4],11,21,[23,25],81],3:[[0,2],4,21,[81,82]],4:[[0,1],[5,8
  387. ],12,[21,24],26,[81,82]],5:[[0,3],11,[21,25],[27,29],81],6:[[0,3],11,21,[23,24],26,[
  388. 81,82]],7:[[0,3],[21,26],81],8:[[0,2],11,[21,22]],9:[[0,3],[21,23],81],10:[[0,3]
  389. ,[21,28],81],11:[[0,3],[21,29]],12:[[0,2],[21,30],81],13:[[0,2],[21,22],[81,82]],
  390. 31:[[0,1],[22,27],30]},44:{0:[0],1:[[0,7],[11,16],[83,84]],2:[[0,5],[21,22],24
  391. ,29,[32,33],[81,82]],3:[[0,1],[3,8]],4:[[0,4]],5:[[0,1],[6,15],23,[82,83]],6:[[0
  392. ,1],[4,8]],7:[[0,1],[3,5],81,[83,85]],8:[[0,4],11,23,25,[81,83]],9:[[0,3],23,[81,
  393. 83]],12:[[0,3],[23,26],[83,84]],13:[[0,3],[22,24],81],14:[[0,2],[21,24],[26,27],81
  394. ],15:[[0,2],21,23,81],16:[[0,2],[21,25]],17:[[0,2],21,23,81],18:[[0,3],21,23,[25
  395. ,27],[81,82]],19:[0],20:[0],51:[[0,3],[21,22]],52:[[0,3],[21,22],24,81],53:[[0
  396. ,2],[21,23],81]},45:{0:[0],1:[[0,9],[21,27]],2:[[0,5],[21,26]],3:[[0,5],[11,12
  397. ],[21,32]],4:[[0,1],[3,6],11,[21,23],81],5:[[0,3],12,21],6:[[0,3],21,81],7:[[0,3
  398. ],[21,22]],8:[[0,4],21,81],9:[[0,3],[21,24],81],10:[[0,2],[21,31]],11:[[0,2],[21
  399. ,23]],12:[[0,2],[21,29],81],13:[[0,2],[21,24],81],14:[[0,2],[21,25],81]},46:{0
  400. :[0],1:[[0,1],[5,8]],2:[[0,1]],3:[0,[21,23]],90:[[0,3],[5,7],[21,39]]},50:{0
  401. :[0],1:[[0,19]],2:[0,[22,38],[40,43]],3:[0,[81,84]]},51:{0:[0],1:[[0,1],[4,8
  402. ],[12,15],[21,24],29,[31,32],[81,84]],3:[[0,4],11,[21,22]],4:[[0,3],11,[21,22]],5:
  403. [[0,4],[21,22],[24,25]],6:[[0,1],3,23,26,[81,83]],7:[[0,1],[3,4],[22,27],81],8:[[0
  404. ,2],[11,12],[21,24]],9:[[0,4],[21,23]],10:[[0,2],11,[24,25],28],11:[[0,2],[11,13],
  405. [23,24],26,29,[32,33],81],13:[[0,4],[21,25],81],14:[[0,2],[21,25]],15:[[0,3],[21,
  406. 29]],16:[[0,3],[21,23],81],17:[[0,3],[21,25],81],18:[[0,3],[21,27]],19:[[0,3],[
  407. 21,23]],20:[[0,2],[21,22],81],32:[0,[21,33]],33:[0,[21,38]],34:[[0,1],[22,37]]},
  408. 52:{0:[0],1:[[0,3],[11,15],[21,23],81],2:[[0,1],3,[21,22]],3:[[0,3],[21,30],[
  409. 81,82]],4:[[0,2],[21,25]],5:[[0,2],[21,27]],6:[[0,3],[21,28]],22:[[0,1],[22,30]]
  410. ,23:[[0,1],[22,28]],24:[[0,1],[22,28]],26:[[0,1],[22,36]],27:[[0,2],[22,23],[25,
  411. 32]]},53:{0:[0],1:[[0,3],[11,14],[21,22],[24,29],81],34:[0,[21,23]],3:[[0,2],[
  412. 21,26],28,81],4:[[0,2],[21,28]],5:[[0,2],[21,24]],6:[[0,2],[21,30]],7:[[0,2],[21
  413. ,24]],8:[[0,2],[21,29]],9:[[0,2],[21,27]],33:[0,21,[23,25]],35:[0,[21,28]],23:
  414. [[0,1],[22,29],31],25:[[0,4],[22,32]],26:[[0,1],[21,28]],27:[[0,1],[22,30]],28:[
  415. [0,1],[22,23]],29:[[0,1],[22,32]],31:[0,[2,3],[22,24]]},54:{0:[0],1:[[0,2],[21
  416. ,27]],21:[0,[21,29],[32,33]],22:[0,[21,29],[31,33]],23:[[0,1],[22,38]],24:[0,[21
  417. ,31]],25:[0,[21,27]],26:[0,[21,27]]},61:{0:[0],1:[[0,4],[11,16],22,[24,26]],
  418. 2:[[0,4],22],3:[[0,4],[21,24],[26,31]],4:[[0,4],[22,31],81],5:[[0,2],[21,28],[81
  419. ,82]],6:[[0,2],[21,32]],7:[[0,2],[21,30]],8:[[0,2],[21,31]],9:[[0,2],[21,29]],
  420. 10:[[0,2],[21,26]]},62:{0:[0],1:[[0,5],11,[21,23]],2:[[0,1]],3:[[0,2],21],
  421. 4:[[0,3],[21,23]],5:[[0,3],[21,25]],6:[[0,2],[21,23]],7:[[0,2],[21,25]],8:[[0,
  422. 2],[21,26]],9:[[0,2],[21,24],[81,82]],10:[[0,2],[21,27]],11:[[0,2],[21,26]],12:[
  423. [0,2],[21,28]],24:[0,21,[24,29]],26:[0,21,[23,30]],29:[[0,1],[21,27]],30:[[0,1],
  424. [21,27]]},63:{0:[0],1:[[0,5],[21,23]],2:[0,2,[21,25]],21:[0,[21,23],[26,28]],
  425. 22:[0,[21,24]],23:[0,[21,24]],25:[0,[21,25]],26:[0,[21,26]],27:[[0,1],[21,26]]
  426. ,28:[[0,2],[21,23]]},64:{0:[0],1:[[0,1],[4,6],[21,22],81],2:[[0,3],5,[21,23]],
  427. 3:[[0,3],[21,24],81],4:[[0,2],[21,25]],5:[[0,2],[21,22]]},65:{0:[0],1:[[0,9]
  428. ,21],2:[[0,5]],32:[[0,1],[21,27]],40:[0,[2,3],[21,28]],42:[[0,2],21,[23,26]],
  429. 43:[[0,1],[21,26]],21:[[0,1],[22,23]],22:[[0,1],[22,23]],23:[[0,3],[23,25],[27,
  430. 28]],90:[[0,4]],27:[[0,2],[22,23]],28:[[0,1],[22,29]],29:[[0,1],[22,29]],30:[[
  431. 0,1],[22,24]],31:[[0,1],[21,31]]},71:{0:[0]},81:{0:[0]},82:{0:[0]}};
  432. var provincial = parseInt(value.substr(0, 2), 10),
  433. prefectural = parseInt(value.substr(2, 2), 10),
  434. county = parseInt(value.substr(4, 2), 10);
  435. if (!china_admin_div_codes[provincial]) { return false; }
  436. if (!china_admin_div_codes[provincial][prefectural]) { return false; }
  437. var in_range = false, range_def = china_admin_div_codes[provincial][prefectural];
  438. for (var i=0; i<range_def.length; i++) {
  439. if (range_def[i] instanceof Array) {
  440. if (range_def[i][0] <= county && county <= range_def[i][1])
  441. { in_range = true; break; }
  442. } else {
  443. if (county == range_def[i]) { in_range = true; break; }
  444. }
  445. }
  446. if (!in_range) { return false; }
  447. // Check date of birth
  448. var dateofbirth_str;
  449. if (value.length == 18) {
  450. dateofbirth_str = value.substr(6, 8);
  451. } else /* length == 15 */ {
  452. dateofbirth_str = "19" + value.substr(6, 6);
  453. }
  454. var year = parseInt(dateofbirth_str.substr(0, 4), 10),
  455. month = parseInt(dateofbirth_str.substr(4, 2), 10),
  456. day = parseInt(dateofbirth_str.substr(6, 2), 10);
  457. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) { return false; }
  458. // Check order code
  459. ; // Already checked by regex. No code here.
  460. // Check checksum (18-digit system only)
  461. if (value.length == 18) {
  462. var sum = 0,
  463. weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  464. for (var i=0; i<17; i++) {
  465. sum += parseInt(value.charAt(i), 10) * weight[i];
  466. }
  467. var correct_checksum = (12 - (sum % 11)) % 11;
  468. var provided_checksum;
  469. if (value.charAt(18-1).toUpperCase() != 'X') {
  470. provided_checksum = parseInt(value.charAt(18-1), 10);
  471. } else { provided_checksum = 10; }
  472. if (provided_checksum != correct_checksum) { return false; }
  473. }
  474. // All rules passed
  475. return true;
  476. // End of validation to citizen identification number of China
  477. },
  478. /**
  479. * Validate Czech national identification number (RC)
  480. * Examples:
  481. * - Valid: 7103192745, 991231123
  482. * - Invalid: 1103492745, 590312123
  483. *
  484. * @param {String} value The ID
  485. * @returns {Boolean}
  486. */
  487. _cz: function(value) {
  488. if (!/^\d{9,10}$/.test(value)) {
  489. return false;
  490. }
  491. var year = 1900 + parseInt(value.substr(0, 2), 10),
  492. month = parseInt(value.substr(2, 2), 10) % 50 % 20,
  493. day = parseInt(value.substr(4, 2), 10);
  494. if (value.length === 9) {
  495. if (year >= 1980) {
  496. year -= 100;
  497. }
  498. if (year > 1953) {
  499. return false;
  500. }
  501. } else if (year < 1954) {
  502. year += 100;
  503. }
  504. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  505. return false;
  506. }
  507. // Check that the birth date is not in the future
  508. if (value.length === 10) {
  509. var check = parseInt(value.substr(0, 9), 10) % 11;
  510. if (year < 1985) {
  511. check = check % 10;
  512. }
  513. return (check + '' === value.substr(9, 1));
  514. }
  515. return true;
  516. },
  517. /**
  518. * Validate Danish Personal Identification number (CPR)
  519. * Examples:
  520. * - Valid: 2110625629, 211062-5629
  521. * - Invalid: 511062-5629
  522. *
  523. * @see https://en.wikipedia.org/wiki/Personal_identification_number_(Denmark)
  524. * @param {String} value The ID
  525. * @returns {Boolean}
  526. */
  527. _dk: function(value) {
  528. if (!/^[0-9]{6}[-]{0,1}[0-9]{4}$/.test(value)) {
  529. return false;
  530. }
  531. value = value.replace(/-/g, '');
  532. var day = parseInt(value.substr(0, 2), 10),
  533. month = parseInt(value.substr(2, 2), 10),
  534. year = parseInt(value.substr(4, 2), 10);
  535. switch (true) {
  536. case ('5678'.indexOf(value.charAt(6)) !== -1 && year >= 58):
  537. year += 1800;
  538. break;
  539. case ('0123'.indexOf(value.charAt(6)) !== -1):
  540. case ('49'.indexOf(value.charAt(6)) !== -1 && year >= 37):
  541. year += 1900;
  542. break;
  543. default:
  544. year += 2000;
  545. break;
  546. }
  547. return $.fn.bootstrapValidator.helpers.date(year, month, day);
  548. },
  549. /**
  550. * Validate Estonian Personal Identification Code (isikukood)
  551. * Examples:
  552. * - Valid: 37605030299
  553. *
  554. * @see http://et.wikipedia.org/wiki/Isikukood
  555. * @param {String} value The ID
  556. * @returns {Boolean}
  557. */
  558. _ee: function(value) {
  559. // Use the same format as Lithuanian Personal Code
  560. return this._lt(value);
  561. },
  562. /**
  563. * Validate Spanish personal identity code (DNI)
  564. * Support i) DNI (for Spanish citizens) and ii) NIE (for foreign people)
  565. *
  566. * Examples:
  567. * - Valid: i) 54362315K, 54362315-K; ii) X2482300W, X-2482300W, X-2482300-W
  568. * - Invalid: i) 54362315Z; ii) X-2482300A
  569. *
  570. * @see https://en.wikipedia.org/wiki/National_identification_number#Spain
  571. * @param {String} value The ID
  572. * @returns {Boolean}
  573. */
  574. _es: function(value) {
  575. if (!/^[0-9A-Z]{8}[-]{0,1}[0-9A-Z]$/.test(value) // DNI
  576. && !/^[XYZ][-]{0,1}[0-9]{7}[-]{0,1}[0-9A-Z]$/.test(value)) { // NIE
  577. return false;
  578. }
  579. value = value.replace(/-/g, '');
  580. var index = 'XYZ'.indexOf(value.charAt(0));
  581. if (index !== -1) {
  582. // It is NIE number
  583. value = index + value.substr(1) + '';
  584. }
  585. var check = parseInt(value.substr(0, 8), 10);
  586. check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
  587. return (check === value.substr(8, 1));
  588. },
  589. /**
  590. * Validate Finnish Personal Identity Code (HETU)
  591. * Examples:
  592. * - Valid: 311280-888Y, 131052-308T
  593. * - Invalid: 131052-308U, 310252-308Y
  594. *
  595. * @param {String} value The ID
  596. * @returns {Boolean}
  597. */
  598. _fi: function(value) {
  599. if (!/^[0-9]{6}[-+A][0-9]{3}[0-9ABCDEFHJKLMNPRSTUVWXY]$/.test(value)) {
  600. return false;
  601. }
  602. var day = parseInt(value.substr(0, 2), 10),
  603. month = parseInt(value.substr(2, 2), 10),
  604. year = parseInt(value.substr(4, 2), 10),
  605. centuries = {
  606. '+': 1800,
  607. '-': 1900,
  608. 'A': 2000
  609. };
  610. year = centuries[value.charAt(6)] + year;
  611. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  612. return false;
  613. }
  614. var individual = parseInt(value.substr(7, 3), 10);
  615. if (individual < 2) {
  616. return false;
  617. }
  618. var n = value.substr(0, 6) + value.substr(7, 3) + '';
  619. n = parseInt(n, 10);
  620. return '0123456789ABCDEFHJKLMNPRSTUVWXY'.charAt(n % 31) === value.charAt(10);
  621. },
  622. /**
  623. * Validate Croatian personal identification number (OIB)
  624. * Examples:
  625. * - Valid: 33392005961
  626. * - Invalid: 33392005962
  627. *
  628. * @param {String} value The ID
  629. * @returns {Boolean}
  630. */
  631. _hr: function(value) {
  632. if (!/^[0-9]{11}$/.test(value)) {
  633. return false;
  634. }
  635. return $.fn.bootstrapValidator.helpers.mod11And10(value);
  636. },
  637. /**
  638. * Validate Irish Personal Public Service Number (PPS)
  639. * Examples:
  640. * - Valid: 6433435F, 6433435FT, 6433435FW, 6433435OA, 6433435IH, 1234567TW, 1234567FA
  641. * - Invalid: 6433435E, 6433435VH
  642. *
  643. * @see https://en.wikipedia.org/wiki/Personal_Public_Service_Number
  644. * @param {String} value The ID
  645. * @returns {Boolean}
  646. */
  647. _ie: function(value) {
  648. if (!/^\d{7}[A-W][AHWTX]?$/.test(value)) {
  649. return false;
  650. }
  651. var getCheckDigit = function(value) {
  652. while (value.length < 7) {
  653. value = '0' + value;
  654. }
  655. var alphabet = 'WABCDEFGHIJKLMNOPQRSTUV',
  656. sum = 0;
  657. for (var i = 0; i < 7; i++) {
  658. sum += parseInt(value.charAt(i), 10) * (8 - i);
  659. }
  660. sum += 9 * alphabet.indexOf(value.substr(7));
  661. return alphabet[sum % 23];
  662. };
  663. // 2013 format
  664. if (value.length === 9 && ('A' === value.charAt(8) || 'H' === value.charAt(8))) {
  665. return value.charAt(7) === getCheckDigit(value.substr(0, 7) + value.substr(8) + '');
  666. }
  667. // The old format
  668. else {
  669. return value.charAt(7) === getCheckDigit(value.substr(0, 7));
  670. }
  671. },
  672. /**
  673. * Validate Iceland national identification number (Kennitala)
  674. * Examples:
  675. * - Valid: 120174-3399, 1201743399, 0902862349
  676. *
  677. * @see http://en.wikipedia.org/wiki/Kennitala
  678. * @param {String} value The ID
  679. * @returns {Boolean}
  680. */
  681. _is: function(value) {
  682. if (!/^[0-9]{6}[-]{0,1}[0-9]{4}$/.test(value)) {
  683. return false;
  684. }
  685. value = value.replace(/-/g, '');
  686. var day = parseInt(value.substr(0, 2), 10),
  687. month = parseInt(value.substr(2, 2), 10),
  688. year = parseInt(value.substr(4, 2), 10),
  689. century = parseInt(value.charAt(9), 10);
  690. year = (century === 9) ? (1900 + year) : ((20 + century) * 100 + year);
  691. if (!$.fn.bootstrapValidator.helpers.date(year, month, day, true)) {
  692. return false;
  693. }
  694. // Validate the check digit
  695. var sum = 0,
  696. weight = [3, 2, 7, 6, 5, 4, 3, 2];
  697. for (var i = 0; i < 8; i++) {
  698. sum += parseInt(value.charAt(i), 10) * weight[i];
  699. }
  700. sum = 11 - sum % 11;
  701. return (sum + '' === value.charAt(8));
  702. },
  703. /**
  704. * Validate Lithuanian Personal Code (Asmens kodas)
  705. * Examples:
  706. * - Valid: 38703181745
  707. * - Invalid: 38703181746, 78703181745, 38703421745
  708. *
  709. * @see http://en.wikipedia.org/wiki/National_identification_number#Lithuania
  710. * @see http://www.adomas.org/midi2007/pcode.html
  711. * @param {String} value The ID
  712. * @returns {Boolean}
  713. */
  714. _lt: function(value) {
  715. if (!/^[0-9]{11}$/.test(value)) {
  716. return false;
  717. }
  718. var gender = parseInt(value.charAt(0), 10),
  719. year = parseInt(value.substr(1, 2), 10),
  720. month = parseInt(value.substr(3, 2), 10),
  721. day = parseInt(value.substr(5, 2), 10),
  722. century = (gender % 2 === 0) ? (17 + gender / 2) : (17 + (gender + 1) / 2);
  723. year = century * 100 + year;
  724. if (!$.fn.bootstrapValidator.helpers.date(year, month, day, true)) {
  725. return false;
  726. }
  727. // Validate the check digit
  728. var sum = 0,
  729. weight = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1];
  730. for (var i = 0; i < 10; i++) {
  731. sum += parseInt(value.charAt(i), 10) * weight[i];
  732. }
  733. sum = sum % 11;
  734. if (sum !== 10) {
  735. return sum + '' === value.charAt(10);
  736. }
  737. // Re-calculate the check digit
  738. sum = 0;
  739. weight = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3];
  740. for (i = 0; i < 10; i++) {
  741. sum += parseInt(value.charAt(i), 10) * weight[i];
  742. }
  743. sum = sum % 11;
  744. if (sum === 10) {
  745. sum = 0;
  746. }
  747. return (sum + '' === value.charAt(10));
  748. },
  749. /**
  750. * Validate Latvian Personal Code (Personas kods)
  751. * Examples:
  752. * - Valid: 161175-19997, 16117519997
  753. * - Invalid: 161375-19997
  754. *
  755. * @see http://laacz.lv/2006/11/25/pk-parbaudes-algoritms/
  756. * @param {String} value The ID
  757. * @returns {Boolean}
  758. */
  759. _lv: function(value) {
  760. if (!/^[0-9]{6}[-]{0,1}[0-9]{5}$/.test(value)) {
  761. return false;
  762. }
  763. value = value.replace(/\D/g, '');
  764. // Check birth date
  765. var day = parseInt(value.substr(0, 2), 10),
  766. month = parseInt(value.substr(2, 2), 10),
  767. year = parseInt(value.substr(4, 2), 10);
  768. year = year + 1800 + parseInt(value.charAt(6), 10) * 100;
  769. if (!$.fn.bootstrapValidator.helpers.date(year, month, day, true)) {
  770. return false;
  771. }
  772. // Check personal code
  773. var sum = 0,
  774. weight = [10, 5, 8, 4, 2, 1, 6, 3, 7, 9];
  775. for (var i = 0; i < 10; i++) {
  776. sum += parseInt(value.charAt(i), 10) * weight[i];
  777. }
  778. sum = (sum + 1) % 11 % 10;
  779. return (sum + '' === value.charAt(10));
  780. },
  781. /**
  782. * Validate Dutch national identification number (BSN)
  783. * Examples:
  784. * - Valid: 111222333, 941331490, 9413.31.490
  785. * - Invalid: 111252333
  786. *
  787. * @see https://nl.wikipedia.org/wiki/Burgerservicenummer
  788. * @param {String} value The ID
  789. * @returns {Boolean}
  790. */
  791. _nl: function(value) {
  792. while (value.length < 9) {
  793. value = '0' + value;
  794. }
  795. if (!/^[0-9]{4}[.]{0,1}[0-9]{2}[.]{0,1}[0-9]{3}$/.test(value)) {
  796. return false;
  797. }
  798. value = value.replace(/\./g, '');
  799. if (parseInt(value, 10) === 0) {
  800. return false;
  801. }
  802. var sum = 0,
  803. length = value.length;
  804. for (var i = 0; i < length - 1; i++) {
  805. sum += (9 - i) * parseInt(value.charAt(i), 10);
  806. }
  807. sum = sum % 11;
  808. if (sum === 10) {
  809. sum = 0;
  810. }
  811. return (sum + '' === value.charAt(length - 1));
  812. },
  813. /**
  814. * Validate Romanian numerical personal code (CNP)
  815. * Examples:
  816. * - Valid: 1630615123457, 1800101221144
  817. * - Invalid: 8800101221144, 1632215123457, 1630615123458
  818. *
  819. * @see http://en.wikipedia.org/wiki/National_identification_number#Romania
  820. * @param {String} value The ID
  821. * @returns {Boolean}
  822. */
  823. _ro: function(value) {
  824. if (!/^[0-9]{13}$/.test(value)) {
  825. return false;
  826. }
  827. var gender = parseInt(value.charAt(0), 10);
  828. if (gender === 0 || gender === 7 || gender === 8) {
  829. return false;
  830. }
  831. // Determine the date of birth
  832. var year = parseInt(value.substr(1, 2), 10),
  833. month = parseInt(value.substr(3, 2), 10),
  834. day = parseInt(value.substr(5, 2), 10),
  835. // The year of date is determined base on the gender
  836. centuries = {
  837. '1': 1900, // Male born between 1900 and 1999
  838. '2': 1900, // Female born between 1900 and 1999
  839. '3': 1800, // Male born between 1800 and 1899
  840. '4': 1800, // Female born between 1800 and 1899
  841. '5': 2000, // Male born after 2000
  842. '6': 2000 // Female born after 2000
  843. };
  844. if (day > 31 && month > 12) {
  845. return false;
  846. }
  847. if (gender !== 9) {
  848. year = centuries[gender + ''] + year;
  849. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  850. return false;
  851. }
  852. }
  853. // Validate the check digit
  854. var sum = 0,
  855. weight = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9],
  856. length = value.length;
  857. for (var i = 0; i < length - 1; i++) {
  858. sum += parseInt(value.charAt(i), 10) * weight[i];
  859. }
  860. sum = sum % 11;
  861. if (sum === 10) {
  862. sum = 1;
  863. }
  864. return (sum + '' === value.charAt(length - 1));
  865. },
  866. /**
  867. * Validate Swedish personal identity number (personnummer)
  868. * Examples:
  869. * - Valid: 8112289874, 811228-9874, 811228+9874
  870. * - Invalid: 811228-9873
  871. *
  872. * @see http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)
  873. * @param {String} value The ID
  874. * @returns {Boolean}
  875. */
  876. _se: function(value) {
  877. if (!/^[0-9]{10}$/.test(value) && !/^[0-9]{6}[-|+][0-9]{4}$/.test(value)) {
  878. return false;
  879. }
  880. value = value.replace(/[^0-9]/g, '');
  881. var year = parseInt(value.substr(0, 2), 10) + 1900,
  882. month = parseInt(value.substr(2, 2), 10),
  883. day = parseInt(value.substr(4, 2), 10);
  884. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  885. return false;
  886. }
  887. // Validate the last check digit
  888. return $.fn.bootstrapValidator.helpers.luhn(value);
  889. },
  890. /**
  891. * Validate Slovak national identifier number (RC)
  892. * Examples:
  893. * - Valid: 7103192745, 991231123
  894. * - Invalid: 7103192746, 1103492745
  895. *
  896. * @param {String} value The ID
  897. * @returns {Boolean}
  898. */
  899. _sk: function(value) {
  900. // Slovakia uses the same format as Czech Republic
  901. return this._cz(value);
  902. },
  903. /**
  904. * Validate San Marino citizen number
  905. *
  906. * @see http://en.wikipedia.org/wiki/National_identification_number#San_Marino
  907. * @param {String} value The ID
  908. * @returns {Boolean}
  909. */
  910. _sm: function(value) {
  911. return /^\d{5}$/.test(value);
  912. },
  913. /**
  914. * Validate South African ID
  915. * Example:
  916. * - Valid: 8001015009087
  917. * - Invalid: 8001015009287, 8001015009086
  918. *
  919. * @see http://en.wikipedia.org/wiki/National_identification_number#South_Africa
  920. * @param {String} value The ID
  921. * @returns {Boolean}
  922. */
  923. _za: function(value) {
  924. if (!/^[0-9]{10}[0|1][8|9][0-9]$/.test(value)) {
  925. return false;
  926. }
  927. var year = parseInt(value.substr(0, 2), 10),
  928. currentYear = new Date().getFullYear() % 100,
  929. month = parseInt(value.substr(2, 2), 10),
  930. day = parseInt(value.substr(4, 2), 10);
  931. year = (year >= currentYear) ? (year + 1900) : (year + 2000);
  932. if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
  933. return false;
  934. }
  935. // Validate the last check digit
  936. return $.fn.bootstrapValidator.helpers.luhn(value);
  937. }
  938. };
  939. }(window.jQuery));