身份证号码的校验,涉及到了香港81、澳门82、台湾83地区的身份证号码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
/** 身份证匹配demo */
var idCard = function (value) {
if (value.length == 18 && 18 != value.length) return false;
var number = value.toLowerCase();
var d, sum = 0,
v = '10x98765432',
w = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
a = '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,83,91';
var re = number.match(/^(\d{2})\d{4}(((\d{2})(\d{2})(\d{2})(\d{3}))|((\d{4})(\d{2})(\d{2})(\d{3}[x\d])))$/);
/**
* match匹配时,个人理解过程是这样的 ,匹配到就返回数组,匹配不到返回 undefined
* 正则表达式为 /^(\d{2})\d{4}(((\d{2})(\d{2})(\d{2})(\d{3}))|((\d{4})(\d{2})(\d{2})(\d{3}[x\d])))$/
* 第一次可分为分为 匹配 (\d{2}) 和 (( (\d{2})(\d{2})(\d{2})(\d{3})) | ((\d{4})(\d{2})(\d{2})(\d{3}[x\d] )))这两大部分
* 匹配结果为 本身整体匹配的字符串 、第一个匹配、第二个匹配的 所以结果为 830000196002100162 , 83 , 196002100162
* 因为第二大部分的里面还涵盖有括号,所以要继续匹配 第二次要匹配的字符串为 undefined(因为没有找到)对应的正则表达式为 (\d{2})(\d{2})(\d{2})(\d{3}) ;
* 196002100162 对应的正则表达式为 (\d{4})(\d{2})(\d{2})(\d{3}[x\d])
* 先匹配 undefined(因为没有找到)对应的正则表达式为 (\d{2})(\d{2})(\d{2})(\d{3}) ,
* 返回结果为自身、第一个、第二个、第三个、第四个 undefined, undefined,undefined,undefined,undefined
* 再匹配 196002100162 对应的正则表达式为 (\d{4})(\d{2})(\d{2})(\d{3}[x\d])
* 返回结果为自身、第一个、第二个、第三个、第四个 196002100162, 1960,02,10,1162
* 因此数组自重结果为 [830000196002100162 , 83 , 196002100162,undefined, undefined,undefined,undefined,undefined,196002100162, 1960,02,10,1162]
*/
if (re == null || a.indexOf(re[1]) < 0) return false;
if (re[2].length == 9) {
number = number.substr(0, 6) + '19' + number.substr(6);
d = ['19' + re[4], re[5], re[6]].join('-');
} else d = [re[9], re[10], re[11]].join('-');
for (var i = 0; i < 17; i++) sum += number.charAt(i) * w[i];
const flag = (re[2].length == 9 || number.charAt(17) == v.charAt(sum % 11));
return flag;
}
idCard("830000196002100162")
</script>
</body>
</html>