JavaScript-求解:js验证身份证号的问题

小组聊天灌水 小组聊天灌水 主题:993 回复:2175

JavaScript-求解:js验证身份证号的问题

归属感 发布于 2017-02-08 字数 295 浏览 1180 回复 4

在咱平台注册上用一个js来验证身份证号的,其中有段是这样的

if (vCid.length == 18)
{
for(var i = 17 ; i >= 0 ; i--) vSum += (Math.pow(2, i) % 11) * parseInt(vCid.charAt(17 - i), 11);
if(vSum % 11 != 1) return false;
}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

支持 Markdown 语法,需要帮助?

评论(4

晚风撩人 2017-09-10 4 楼

String.prototype.isIDCard = function()
{
var vCid = this.trim();
var vSum = 0;
var vReg = /^([d]{17}[xXd]|[d]{15})$/;
var vCity = '|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 (!vReg.test(vCid)) return false;

if(vCity.indexOf(parseInt(vCid.substr(0,2))) == '-1') return false;

vCid = vCid.replace(/[xX]$/i, 'a');

if (vCid.length == 18)
{
    vBirthday = vCid.substr(6, 4) + '/' + Number(vCid.substr(10, 2)) + '/' + Number(vCid.substr(12, 2));
} else {
    vBirthday = '19' + vCid.substr(6, 2) + '/' + Number(vCid.substr(8, 2)) + '/' + Number(vCid.substr(10, 2));
}

var vDate = new Date(vBirthday);

if (vBirthday != (vDate.getFullYear() + '/' + (vDate.getMonth() + 1) + '/' + vDate.getDate())) return false;

if (vCid.length == 18)
{
    for(var i = 17 ; i >= 0 ; i--) vSum += (Math.pow(2, i) % 11) * parseInt(vCid.charAt(17 - i), 11);
    if(vSum % 11 != 1) return false;
}

return true;

}

泛泛之交 2017-06-30 3 楼

身份证号码的第15和16位数字代表所在地的派出所的代码;第17位数字表示性别(奇数表示男性,偶数表示女性);第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,而这位校验码是通过前17位和一些加权因子生成的

加权因子: Wi = [ 7, 9, 10, 5, 8, 4, 2, 1,6, 3, 7, 9, 10, 5, 8, 4, 2,1 ]
验证位 Y =[ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 )
i为身份证号码从右往左数的 2...18 位;
Y_P为脚丫校验码所在校验码数组位置

清晨说ぺ晚安 2017-05-17 2 楼

首先先看一下以下关于身份证号码规则的解释:

地址码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日分别用4位、2位、2位数字表示,之间不用分隔符。
顺序码:四位,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。(但是由于某些地方的管理疏漏奇偶分配可能不准确)
校验码为“X”(大写),为防止重复(是将最后一位顺序吗改为X,保证身份证号码已然是18位)
15位身份证号码是1999年之前的,个别人的还没到期,仍能用。
举例如下:
北京市朝阳区: 11010519491231002X
广东省汕头市: 440524188001010014

校验的计算方式:

  1. 对前17位数字本体码加权求和
    公式为:S = Sum(Ai * Wi), i = 0, ... , 16
    其中Ai表示第i位置上的身份证号码数字值,Wi表示第i位置上的加权因子,其各位对应的值依次为: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

以11对计算结果取模
Y = mod(S, 11)
根据模的值得到对应的校验码
对应关系为:
Y值: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
身份证号码的编排规则

身份证号码中这些数字是怎样排列的,每个数字表示什么意思呢?下面就让我们一起来探索其中的规律吧!新的身份证号码是由18位数字组成的,它们分别表示:

(1)前1、2位数字表示:所在省份的代码;
(2)第3、4位数字表示:所在城市的代码;
(3)第5、6位数字表示:所在区县的代码;
(4)第7~14位数字表示:出生年、月、日;
(5)第15、16位数字表示:所在地的派出所的代码;
(6)第17位数字表示性别:奇数表示男性,偶数表示女性;
(7)第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,
用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。

15位的身份证号
dddddd yymmdd xx p
18位的身份证号
dddddd yyyymmdd xx p y
其中dddddd为地址码(省地县三级)18位中的和15位中的不完全相同
yyyymmdd yymmdd 为出生年月日
xx顺号类编码
p性别
18位中末尾的y为校验码,在网上可以找到算法
将前17位的ascii码值经位移、异或运算结果不在0-9的令其为x

 //以下是JavaScript对身份证的验证:
/****/
<script language="javascript">
/**

  • 身份证15位编码规则:dddddd yymmdd xx p
  • dddddd:地区码
  • yymmdd: 出生年月日
  • xx: 顺序类编码,无法确定
  • p: 性别,奇数为男,偶数为女
  • <p />
  • 身份证18位编码规则:dddddd yyyymmdd xxx y
  • dddddd:地区码
  • yyyymmdd: 出生年月日
  • xxx:顺序类编码,无法确定,奇数为男,偶数为女
  • y: 校验码,该位数值可通过前17位计算获得
  • <p />
  • 18位号码加权因子为(从右到左) Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2,1 ]
  • 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
  • 校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 )
  • i为身份证号码从右往左数的 2...18 位; Y_P为脚丫校验码所在校验码数组位置
  • */

var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ];// 加权因子
var ValideCode = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ];// 身份证验证位值.10代表X
function IdCardValidate(idCard) {
<coding-3 lang="other">
idCard = trim(idCard.replace(/ /g, ""));
if (idCard.length == 15) {
return isValidityBrithBy15IdCard(idCard);
} else if (idCard.length == 18) {
var a_idCard = idCard.split("");// 得到身份证数组
if(isValidityBrithBy18IdCard(idCard)&&isTrueValidateCodeBy18IdCard(a_idCard)){
return true;
}else {
return false;
}
} else {
return false;
}
}
/**

  • 判断身份证号码为18位时最后的验证位是否正确
  • @param a_idCard 身份证号码数组
  • @return
    /
    function isTrueValidateCodeBy18IdCard(a_idCard) {
    <coding-4 lang="other">
    var sum = 0; // 声明加权求和变量
    if (a_idCard[17].toLowerCase() == 'x') {
    a_idCard[17] = 10;// 将最后位为x的验证码替换为10方便后续操作
    }
    for ( var i = 0; i < 17; i++) {
    sum += Wi[i]
    a_idCard[i];// 加权求和
    }
    valCodePosition = sum % 11;// 得到验证码所位置
    if (a_idCard[17] == ValideCode[valCodePosition]) {
    return true;
    } else {
    return false;
    }
    }
    /**
  • 通过身份证判断是男是女
  • @param idCard 15/18位身份证号码
  • @return 'female'-女、'male'-男
    */
    function maleOrFemalByIdCard(idCard){
    idCard = trim(idCard.replace(/ /g, ""));// 对身份证号码做处理。包括字符间有空格。
    if(idCard.length==15){
    if(idCard.substring(14,15)%2==0){
    return 'female';
    }else{
    return 'male';
    }
    }else if(idCard.length ==18){
    if(idCard.substring(14,17)%2==0){
    return 'female';
    }else{
    return 'male';
    }
    }else{
    return null;
    }

// 可对传入字符直接当作数组来处理
// if(idCard.length==15){
// alert(idCard[13]);
// if(idCard[13]%2==0){
// return 'female';
// }else{
// return 'male';
// }
// }else if(idCard.length==18){
// alert(idCard[16]);
// if(idCard[16]%2==0){
// return 'female';
// }else{
// return 'male';
// }
// }else{
// return null;
// }
}
/**

  • 验证18位数身份证号码中的生日是否是有效生日
  • @param idCard 18位书身份证字符串
  • @return
    */
    function isValidityBrithBy18IdCard(idCard18){
    var year = idCard18.substring(6,10);
    var month = idCard18.substring(10,12);
    var day = idCard18.substring(12,14);
    var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));
    // 这里用getFullYear()获取年份,避免千年虫问题
    if(temp_date.getFullYear()!=parseFloat(year)
    ||temp_date.getMonth()!=parseFloat(month)-1
    ||temp_date.getDate()!=parseFloat(day)){
    return false;
    }else{
    return true;
    }

}
/**

  • 验证15位数身份证号码中的生日是否是有效生日
  • @param idCard15 15位书身份证字符串
  • @return
    /
    function isValidityBrithBy15IdCard(idCard15){
    var year = idCard15.substring(6,8);
    var month = idCard15.substring(8,10);
    var day = idCard15.substring(10,12);
    var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));
    // 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
    if(temp_date.getYear()!=parseFloat(year)
    ||temp_date.getMonth()!=parseFloat(month)-1
    ||temp_date.getDate()!=parseFloat(day)){
    return false;
    }else{
    return true;
    }
    }
    //去掉字符串头尾空格
    function trim(str) {
    return str.replace(/(^s
    )|(s*$)/g, "");

}
</script>

虐人心 2017-02-21 1 楼

这是以前收藏以为高人的,分享给你,很好用的,我的程序一直在用这个,你可以试一试的:

 //身份证号合法性验证
//支持15位和18位身份证号
//支持地址编码、出生日期、校验位验证
function IdentityCodeValid(code) {
var city={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 tip = "";
var pass= true;

      if(!code || !/^d{6}(18|19|20)?d{2}(0[1-9]|1[12])(0[1-9]|[12]d|3[01])d{3}(d|X)$/i.test(code)){
          tip = "身份证号格式错误";
          pass = false;
      }

     else if(!city[code.substr(0,2)]){
          tip = "地址编码错误";
          pass = false;
      }
      else{
          //18位身份证需要验证最后一位校验位
          if(code.length == 18){
              code = code.split('');
              //∑(ai×Wi)(mod 11)
              //加权因子
              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;
              var ai = 0;
              var wi = 0;
              for (var i = 0; i &lt; 17; i++)
              {
                  ai = code[i];
                  wi = factor[i];
                  sum += ai * wi;
              }
              var last = parity[sum % 11];
              if(parity[sum % 11] != code[17]){
                  tip = "校验位错误";
                  pass =false;
              }
          }
      }
      if(!pass) alert(tip);
      return pass;
  }
    var idcord = '140981199312253466';
    var res= IdentityCodeValid(idcord);

alert(res);