根据1999年7月1日推出的《中华人民共和国国家标准》(GB 11643-1999)中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成;排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
出生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。
校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
一个简单的测试页面
<html>
<head>
<script type="text/javascript">
function input_id_number(obj){
;
}
</script>
</head>
<body>
<form>
<input type="text" maxlength="18" onfocus="javascript:this.value='';" onkeyup="input_id_number(this)" onblur="input_id_number(this)" value="请输入身份证号"/>
</form>
</body>
</html>
现在我们来写这个函数。
首先保证用户输入的值前十七位为数字,最后一位只能为数字或者字母x,长度不能超过18位;
function input_id_number(obj) {
var n = obj.value.match(/\d{0,17}(\d|x)/i);
obj.value = n===null ? '' : n[0];
if (obj.value.length == 18) {
;
}
}
现在我们开始写验证身份证有效性的函数
function check_id_number(obj) {
var n = obj.value.match(/^[1-9][1-7]\d{4}(18|19|20)?\d{2}((0[1-9])|(1[012]))((0[1-9])|([12]\d)|(3[01]))\d{3}(\d|x)$/i);
if (n===null) {
obj.value = '身份证号码有误,请重新输入';
return false;
} else {
obj.value = n[0];
}
var p={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:'国外'};
if (!p[obj.value.substr(0,2)]) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
var month = obj.value.substr(10,2);
var day = obj.value.substr(12,2);
var max_month = '01,03,05,07,08,10,12,';
if (max_month.indexOf(month + ',') < 0 && day == 31) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
if (month == '02') {
if (day > 29) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
var year = obj.value.substr(6,4);
if ((year%4>0 || (year % 100 == 0 && year % 400 >0)) && day == 29) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
}
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
var parity = [1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
for (var i = 0; i < 17; ++i)
{
sum += obj.value[i] * factor[i];
}
if (obj.value[17] == 'X') {
obj.value[17] = 'x';
}
if(parity[sum % 11] != obj.value[17]){
obj.value = '身份证号码有误,请重新输入';
return false;
}
}
组合在一起:
function input_id_number(obj) {
var n = obj.value.match(/\d{0,17}(\d|x)/i);
obj.value = n===null ? '' : n[0];
if (obj.value.length == 18) {
check_id_number(obj);
}
}
function check_id_number(obj) {
var n = obj.value.match(/^[1-9][1-7]\d{4}(18|19|20)?\d{2}((0[1-9])|(1[012]))((0[1-9])|([12]\d)|(3[01]))\d{3}(\d|x)$/i);
if (n===null) {
obj.value = '身份证号码有误,请重新输入';
return false;
} else {
obj.value = n[0];
}
var p={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:'国外'};
if (!p[obj.value.substr(0,2)]) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
var month = obj.value.substr(10,2);
var day = obj.value.substr(12,2);
var max_month = '01,03,05,07,08,10,12,';
if (max_month.indexOf(month + ',') < 0 && day == 31) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
if (month == '02') {
if (day > 29) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
var year = obj.value.substr(6,4);
if ((year%4>0 || (year % 100 == 0 && year % 400 >0)) && day == 29) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
}
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
var parity = [1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
for (var i = 0; i < 17; ++i)
{
sum += obj.value[i] * factor[i];
}
if (obj.value[17] == 'X') {
obj.value[17] = 'x';
}
if(parity[sum % 11] != obj.value[17]){
obj.value = '身份证号码有误,请重新输入';
return false;
}
}
最终我们的测试页面是这样的:
<html>
<head>
<script type="text/javascript">
function input_id_number(obj) {
var n = obj.value.match(/\d{0,17}(\d|x)/i);
obj.value = n===null ? '' : n[0];
if (obj.value.length == 18) {
check_id_number(obj);
}
}
function check_id_number(obj) {
var n = obj.value.match(/^[1-9][1-7]\d{4}(18|19|20)?\d{2}((0[1-9])|(1[012]))((0[1-9])|([12]\d)|(3[01]))\d{3}(\d|x)$/i);
if (n === null) {
obj.value = '身份证号码有误,请重新输入';
return false;
} else {
obj.value = n[0];
}
var p={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:'国外'};
if (!p[obj.value.substr(0,2)]) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
var month = obj.value.substr(10,2);
var day = obj.value.substr(12,2);
var max_month = '01,03,05,07,08,10,12,';
if (max_month.indexOf(month + ',') < 0 && day == 31) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
if (month == '02') {
if (day > 29) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
var year = obj.value.substr(6,4);
if ((year%4>0 || (year % 100 == 0 && year % 400 >0)) && day == 29) {
obj.value = '身份证号码有误,请重新输入';
return false;
}
}
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
var parity = [1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
for (var i = 0; i < 17; ++i)
{
sum += obj.value[i] * factor[i];
}
if (obj.value[17] == 'X') {
obj.value[17] = 'x';
}
if(parity[sum % 11] != obj.value[17]){
obj.value = '身份证号码有误,请重新输入';
return false;
}
}
</script>
</head>
<body>
<form>
<input type="text" maxlength="18" onfocus="javascript:this.value='';" onkeyup="input_id_number(this)" onblur="check_id_number(this)" value="请输入身份证号"/>
</form>
</body>
</html>