775ac7b58c
you must login with an BTP account in order to see the app
369 lines
No EOL
11 KiB
JavaScript
369 lines
No EOL
11 KiB
JavaScript
import assertString from './util/assertString';
|
|
import isInt from './isInt';
|
|
var validators = {
|
|
PL: function PL(str) {
|
|
assertString(str);
|
|
var weightOfDigits = {
|
|
1: 1,
|
|
2: 3,
|
|
3: 7,
|
|
4: 9,
|
|
5: 1,
|
|
6: 3,
|
|
7: 7,
|
|
8: 9,
|
|
9: 1,
|
|
10: 3,
|
|
11: 0
|
|
};
|
|
|
|
if (str != null && str.length === 11 && isInt(str, {
|
|
allow_leading_zeroes: true
|
|
})) {
|
|
var digits = str.split('').slice(0, -1);
|
|
var sum = digits.reduce(function (acc, digit, index) {
|
|
return acc + Number(digit) * weightOfDigits[index + 1];
|
|
}, 0);
|
|
var modulo = sum % 10;
|
|
var lastDigit = Number(str.charAt(str.length - 1));
|
|
|
|
if (modulo === 0 && lastDigit === 0 || lastDigit === 10 - modulo) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
},
|
|
ES: function ES(str) {
|
|
assertString(str);
|
|
var DNI = /^[0-9X-Z][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/;
|
|
var charsValue = {
|
|
X: 0,
|
|
Y: 1,
|
|
Z: 2
|
|
};
|
|
var controlDigits = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E']; // sanitize user input
|
|
|
|
var sanitized = str.trim().toUpperCase(); // validate the data structure
|
|
|
|
if (!DNI.test(sanitized)) {
|
|
return false;
|
|
} // validate the control digit
|
|
|
|
|
|
var number = sanitized.slice(0, -1).replace(/[X,Y,Z]/g, function (_char) {
|
|
return charsValue[_char];
|
|
});
|
|
return sanitized.endsWith(controlDigits[number % 23]);
|
|
},
|
|
FI: function FI(str) {
|
|
// https://dvv.fi/en/personal-identity-code#:~:text=control%20character%20for%20a-,personal,-identity%20code%20calculated
|
|
assertString(str);
|
|
|
|
if (str.length !== 11) {
|
|
return false;
|
|
}
|
|
|
|
if (!str.match(/^\d{6}[\-A\+]\d{3}[0-9ABCDEFHJKLMNPRSTUVWXY]{1}$/)) {
|
|
return false;
|
|
}
|
|
|
|
var checkDigits = '0123456789ABCDEFHJKLMNPRSTUVWXY';
|
|
var idAsNumber = parseInt(str.slice(0, 6), 10) * 1000 + parseInt(str.slice(7, 10), 10);
|
|
var remainder = idAsNumber % 31;
|
|
var checkDigit = checkDigits[remainder];
|
|
return checkDigit === str.slice(10, 11);
|
|
},
|
|
IN: function IN(str) {
|
|
var DNI = /^[1-9]\d{3}\s?\d{4}\s?\d{4}$/; // multiplication table
|
|
|
|
var d = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]]; // permutation table
|
|
|
|
var p = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]]; // sanitize user input
|
|
|
|
var sanitized = str.trim(); // validate the data structure
|
|
|
|
if (!DNI.test(sanitized)) {
|
|
return false;
|
|
}
|
|
|
|
var c = 0;
|
|
var invertedArray = sanitized.replace(/\s/g, '').split('').map(Number).reverse();
|
|
invertedArray.forEach(function (val, i) {
|
|
c = d[c][p[i % 8][val]];
|
|
});
|
|
return c === 0;
|
|
},
|
|
IR: function IR(str) {
|
|
if (!str.match(/^\d{10}$/)) return false;
|
|
str = "0000".concat(str).substr(str.length - 6);
|
|
if (parseInt(str.substr(3, 6), 10) === 0) return false;
|
|
var lastNumber = parseInt(str.substr(9, 1), 10);
|
|
var sum = 0;
|
|
|
|
for (var i = 0; i < 9; i++) {
|
|
sum += parseInt(str.substr(i, 1), 10) * (10 - i);
|
|
}
|
|
|
|
sum %= 11;
|
|
return sum < 2 && lastNumber === sum || sum >= 2 && lastNumber === 11 - sum;
|
|
},
|
|
IT: function IT(str) {
|
|
if (str.length !== 9) return false;
|
|
if (str === 'CA00000AA') return false; // https://it.wikipedia.org/wiki/Carta_d%27identit%C3%A0_elettronica_italiana
|
|
|
|
return str.search(/C[A-Z][0-9]{5}[A-Z]{2}/i) > -1;
|
|
},
|
|
NO: function NO(str) {
|
|
var sanitized = str.trim();
|
|
if (isNaN(Number(sanitized))) return false;
|
|
if (sanitized.length !== 11) return false;
|
|
if (sanitized === '00000000000') return false; // https://no.wikipedia.org/wiki/F%C3%B8dselsnummer
|
|
|
|
var f = sanitized.split('').map(Number);
|
|
var k1 = (11 - (3 * f[0] + 7 * f[1] + 6 * f[2] + 1 * f[3] + 8 * f[4] + 9 * f[5] + 4 * f[6] + 5 * f[7] + 2 * f[8]) % 11) % 11;
|
|
var k2 = (11 - (5 * f[0] + 4 * f[1] + 3 * f[2] + 2 * f[3] + 7 * f[4] + 6 * f[5] + 5 * f[6] + 4 * f[7] + 3 * f[8] + 2 * k1) % 11) % 11;
|
|
if (k1 !== f[9] || k2 !== f[10]) return false;
|
|
return true;
|
|
},
|
|
TH: function TH(str) {
|
|
if (!str.match(/^[1-8]\d{12}$/)) return false; // validate check digit
|
|
|
|
var sum = 0;
|
|
|
|
for (var i = 0; i < 12; i++) {
|
|
sum += parseInt(str[i], 10) * (13 - i);
|
|
}
|
|
|
|
return str[12] === ((11 - sum % 11) % 10).toString();
|
|
},
|
|
LK: function LK(str) {
|
|
var old_nic = /^[1-9]\d{8}[vx]$/i;
|
|
var new_nic = /^[1-9]\d{11}$/i;
|
|
if (str.length === 10 && old_nic.test(str)) return true;else if (str.length === 12 && new_nic.test(str)) return true;
|
|
return false;
|
|
},
|
|
'he-IL': function heIL(str) {
|
|
var DNI = /^\d{9}$/; // sanitize user input
|
|
|
|
var sanitized = str.trim(); // validate the data structure
|
|
|
|
if (!DNI.test(sanitized)) {
|
|
return false;
|
|
}
|
|
|
|
var id = sanitized;
|
|
var sum = 0,
|
|
incNum;
|
|
|
|
for (var i = 0; i < id.length; i++) {
|
|
incNum = Number(id[i]) * (i % 2 + 1); // Multiply number by 1 or 2
|
|
|
|
sum += incNum > 9 ? incNum - 9 : incNum; // Sum the digits up and add to total
|
|
}
|
|
|
|
return sum % 10 === 0;
|
|
},
|
|
'ar-LY': function arLY(str) {
|
|
// Libya National Identity Number NIN is 12 digits, the first digit is either 1 or 2
|
|
var NIN = /^(1|2)\d{11}$/; // sanitize user input
|
|
|
|
var sanitized = str.trim(); // validate the data structure
|
|
|
|
if (!NIN.test(sanitized)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
'ar-TN': function arTN(str) {
|
|
var DNI = /^\d{8}$/; // sanitize user input
|
|
|
|
var sanitized = str.trim(); // validate the data structure
|
|
|
|
if (!DNI.test(sanitized)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
'zh-CN': function zhCN(str) {
|
|
var provincesAndCities = ['11', // 北京
|
|
'12', // 天津
|
|
'13', // 河北
|
|
'14', // 山西
|
|
'15', // 内蒙古
|
|
'21', // 辽宁
|
|
'22', // 吉林
|
|
'23', // 黑龙江
|
|
'31', // 上海
|
|
'32', // 江苏
|
|
'33', // 浙江
|
|
'34', // 安徽
|
|
'35', // 福建
|
|
'36', // 江西
|
|
'37', // 山东
|
|
'41', // 河南
|
|
'42', // 湖北
|
|
'43', // 湖南
|
|
'44', // 广东
|
|
'45', // 广西
|
|
'46', // 海南
|
|
'50', // 重庆
|
|
'51', // 四川
|
|
'52', // 贵州
|
|
'53', // 云南
|
|
'54', // 西藏
|
|
'61', // 陕西
|
|
'62', // 甘肃
|
|
'63', // 青海
|
|
'64', // 宁夏
|
|
'65', // 新疆
|
|
'71', // 台湾
|
|
'81', // 香港
|
|
'82', // 澳门
|
|
'91' // 国外
|
|
];
|
|
var powers = ['7', '9', '10', '5', '8', '4', '2', '1', '6', '3', '7', '9', '10', '5', '8', '4', '2'];
|
|
var parityBit = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
|
|
|
var checkAddressCode = function checkAddressCode(addressCode) {
|
|
return provincesAndCities.includes(addressCode);
|
|
};
|
|
|
|
var checkBirthDayCode = function checkBirthDayCode(birDayCode) {
|
|
var yyyy = parseInt(birDayCode.substring(0, 4), 10);
|
|
var mm = parseInt(birDayCode.substring(4, 6), 10);
|
|
var dd = parseInt(birDayCode.substring(6), 10);
|
|
var xdata = new Date(yyyy, mm - 1, dd);
|
|
|
|
if (xdata > new Date()) {
|
|
return false; // eslint-disable-next-line max-len
|
|
} else if (xdata.getFullYear() === yyyy && xdata.getMonth() === mm - 1 && xdata.getDate() === dd) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
var getParityBit = function getParityBit(idCardNo) {
|
|
var id17 = idCardNo.substring(0, 17);
|
|
var power = 0;
|
|
|
|
for (var i = 0; i < 17; i++) {
|
|
power += parseInt(id17.charAt(i), 10) * parseInt(powers[i], 10);
|
|
}
|
|
|
|
var mod = power % 11;
|
|
return parityBit[mod];
|
|
};
|
|
|
|
var checkParityBit = function checkParityBit(idCardNo) {
|
|
return getParityBit(idCardNo) === idCardNo.charAt(17).toUpperCase();
|
|
};
|
|
|
|
var check15IdCardNo = function check15IdCardNo(idCardNo) {
|
|
var check = /^[1-9]\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}$/.test(idCardNo);
|
|
if (!check) return false;
|
|
var addressCode = idCardNo.substring(0, 2);
|
|
check = checkAddressCode(addressCode);
|
|
if (!check) return false;
|
|
var birDayCode = "19".concat(idCardNo.substring(6, 12));
|
|
check = checkBirthDayCode(birDayCode);
|
|
if (!check) return false;
|
|
return true;
|
|
};
|
|
|
|
var check18IdCardNo = function check18IdCardNo(idCardNo) {
|
|
var check = /^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}(\d|x|X)$/.test(idCardNo);
|
|
if (!check) return false;
|
|
var addressCode = idCardNo.substring(0, 2);
|
|
check = checkAddressCode(addressCode);
|
|
if (!check) return false;
|
|
var birDayCode = idCardNo.substring(6, 14);
|
|
check = checkBirthDayCode(birDayCode);
|
|
if (!check) return false;
|
|
return checkParityBit(idCardNo);
|
|
};
|
|
|
|
var checkIdCardNo = function checkIdCardNo(idCardNo) {
|
|
var check = /^\d{15}|(\d{17}(\d|x|X))$/.test(idCardNo);
|
|
if (!check) return false;
|
|
|
|
if (idCardNo.length === 15) {
|
|
return check15IdCardNo(idCardNo);
|
|
}
|
|
|
|
return check18IdCardNo(idCardNo);
|
|
};
|
|
|
|
return checkIdCardNo(str);
|
|
},
|
|
'zh-TW': function zhTW(str) {
|
|
var ALPHABET_CODES = {
|
|
A: 10,
|
|
B: 11,
|
|
C: 12,
|
|
D: 13,
|
|
E: 14,
|
|
F: 15,
|
|
G: 16,
|
|
H: 17,
|
|
I: 34,
|
|
J: 18,
|
|
K: 19,
|
|
L: 20,
|
|
M: 21,
|
|
N: 22,
|
|
O: 35,
|
|
P: 23,
|
|
Q: 24,
|
|
R: 25,
|
|
S: 26,
|
|
T: 27,
|
|
U: 28,
|
|
V: 29,
|
|
W: 32,
|
|
X: 30,
|
|
Y: 31,
|
|
Z: 33
|
|
};
|
|
var sanitized = str.trim().toUpperCase();
|
|
if (!/^[A-Z][0-9]{9}$/.test(sanitized)) return false;
|
|
return Array.from(sanitized).reduce(function (sum, number, index) {
|
|
if (index === 0) {
|
|
var code = ALPHABET_CODES[number];
|
|
return code % 10 * 9 + Math.floor(code / 10);
|
|
}
|
|
|
|
if (index === 9) {
|
|
return (10 - sum % 10 - Number(number)) % 10 === 0;
|
|
}
|
|
|
|
return sum + Number(number) * (9 - index);
|
|
}, 0);
|
|
}
|
|
};
|
|
export default function isIdentityCard(str, locale) {
|
|
assertString(str);
|
|
|
|
if (locale in validators) {
|
|
return validators[locale](str);
|
|
} else if (locale === 'any') {
|
|
for (var key in validators) {
|
|
// https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
|
|
// istanbul ignore else
|
|
if (validators.hasOwnProperty(key)) {
|
|
var validator = validators[key];
|
|
|
|
if (validator(str)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
throw new Error("Invalid locale '".concat(locale, "'"));
|
|
} |