黑马程序员技术交流社区

标题: 验证身份证号码是否合法的算法 [打印本页]

作者: hhmm665544    时间: 2014-4-20 23:20
标题: 验证身份证号码是否合法的算法
验证身份证号码是否合法的算法
我随便输入18位或者15位数字,先用正则表达式判断长度是否正确,然后再确定前面前面的地区和出生年月是否正确,后面那4个数字或字母怎么判断呢?
作者: ノtrack    时间: 2014-4-20 23:25
  1. Js代码  收藏代码
  2. function checkCardId(socialNo){  
  3.   
  4.       if(socialNo == "")  
  5.       {  
  6.         alert("输入身份证号码不能为空!");  
  7.         return (false);  
  8.       }  
  9.   
  10.       if (socialNo.length != 15 && socialNo.length != 18)  
  11.       {  
  12.         alert("输入身份证号码格式不正确!");  
  13.         return (false);  
  14.       }  
  15.          
  16.      var area={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:"国外"};   
  17.          
  18.        if(area[parseInt(socialNo.substr(0,2))]==null) {  
  19.         alert("身份证号码不正确(地区非法)!");  
  20.             return (false);  
  21.        }   
  22.               
  23.       if (socialNo.length == 15)  
  24.       {  
  25.          pattern= /^\d{15}$/;  
  26.          if (pattern.exec(socialNo)==null){  
  27.             alert("15位身份证号码必须为数字!");  
  28.             return (false);  
  29.         }  
  30.         var birth = parseInt("19" + socialNo.substr(6,2));  
  31.         var month = socialNo.substr(8,2);  
  32.         var day = parseInt(socialNo.substr(10,2));  
  33.         switch(month) {  
  34.             case '01':  
  35.             case '03':  
  36.             case '05':  
  37.             case '07':  
  38.             case '08':  
  39.             case '10':  
  40.             case '12':  
  41.                 if(day>31) {  
  42.                     alert('输入身份证号码不格式正确!');  
  43.                     return false;  
  44.                 }  
  45.                 break;  
  46.             case '04':  
  47.             case '06':  
  48.             case '09':  
  49.             case '11':  
  50.                 if(day>30) {  
  51.                     alert('输入身份证号码不格式正确!');  
  52.                     return false;  
  53.                 }  
  54.                 break;  
  55.             case '02':  
  56.                 if((birth % 4 == 0 && birth % 100 != 0) || birth % 400 == 0) {  
  57.                     if(day>29) {  
  58.                         alert('输入身份证号码不格式正确!');  
  59.                         return false;  
  60.                     }  
  61.                 } else {  
  62.                     if(day>28) {  
  63.                         alert('输入身份证号码不格式正确!');  
  64.                         return false;  
  65.                     }  
  66.                 }  
  67.                 break;  
  68.             default:  
  69.                 alert('输入身份证号码不格式正确!');  
  70.                 return false;  
  71.         }  
  72.         var nowYear = new Date().getYear();  
  73.         if(nowYear - parseInt(birth)<15 || nowYear - parseInt(birth)>100) {  
  74.             alert('输入身份证号码不格式正确!');  
  75.             return false;  
  76.         }  
  77.         return (true);  
  78.       }  
  79.         
  80.       var Wi = new Array(  
  81.                 7,9,10,5,8,4,2,1,6,  
  82.                 3,7,9,10,5,8,4,2,1  
  83.                 );  
  84.       var   lSum        = 0;  
  85.       var   nNum        = 0;  
  86.       var   nCheckSum   = 0;  
  87.         
  88.         for (i = 0; i < 17; ++i)  
  89.         {  
  90.               
  91.   
  92.             if ( socialNo.charAt(i) < '0' || socialNo.charAt(i) > '9' )  
  93.             {  
  94.                 alert("输入身份证号码格式不正确!");  
  95.                 return (false);  
  96.             }  
  97.             else  
  98.             {  
  99.                 nNum = socialNo.charAt(i) - '0';  
  100.             }  
  101.              lSum += nNum * Wi[i];  
  102.         }  
  103.   
  104.         
  105.         if( socialNo.charAt(17) == 'X' || socialNo.charAt(17) == 'x')  
  106.         {  
  107.             lSum += 10*Wi[17];  
  108.         }  
  109.         else if ( socialNo.charAt(17) < '0' || socialNo.charAt(17) > '9' )  
  110.         {  
  111.             alert("输入身份证号码格式不正确!");  
  112.             return (false);  
  113.         }  
  114.         else  
  115.         {  
  116.             lSum += ( socialNo.charAt(17) - '0' ) * Wi[17];  
  117.         }  
  118.   
  119.          
  120.          
  121.         if ( (lSum % 11) == 1 )  
  122.         {  
  123.             return true;  
  124.         }  
  125.         else  
  126.         {  
  127.             alert("输入身份证号码格式不正确!");  
  128.             return (false);  
  129.         }  
  130.          
  131. }
复制代码

作者: 曹冬明    时间: 2014-4-20 23:58
合法与不合法怎么也该有个限定吧,前面6为是所在地区代码,你是否要有个限定,怎样算合法,还是建立一个数据库,把全国的地区代码都存进去啊;中间8为是出生年月,月和日倒是有限定,年份总该有个限定吧,2038年的行不行,1900年的行不行,后面4位是所在派出所代码,怎么算合法怎么不合法!所以,我说,你至少有个规矩去遵循啊,要不哥们我真是无从下手啊
作者: hhmm665544    时间: 2014-4-21 09:39
我求的是身份证的算法,至于你说的数据库不太可能
作者: kuroro自走核炮    时间: 2014-4-21 09:53
公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。可以用字母表示如为 ABCDEFYYYYMMDDXXXR。其含义如下:  1. 地址码(ABCDEF):表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按 GB/T2260 的规定执行。  
2. 出生日期码(YYYYMMDD):表示编码对象出生的年、月、日,按 GB/T7408 的规定执行,年、月、日分别用 4 位、2 位(不足两位加 0)、2(同上)位数字表示,之间不用分隔符。
3. 顺序码(XXX):表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。  
4.校验码(R):一位数字,通过前 17 位数字按照 ISO 7064:1983.MOD 11-2 校验码计算得出
关于地址码我刚才查了下,貌似第一位取值范围是1-8,那么正则表达式可以写成 :[1-8][0-9]{5}   //首位一至8的六位数字。
然后第二个,出生日期码。首先网站用户的出生年范围,我觉得咱们可以取1900-2099 那么就是 (19|20)[0-9]{2}月份(0[1-9]|1[0-2])日期(0[1-9]|1[0-9]|2[0-9]|3[0-1]) 连起来就是(19|20)[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])
第三个,顺序码。这个不清楚具体规则,就用数字判断吧[0-9]{3}
最后校验码 是允许x的 ([0-9]|x)
这样就得到对18位身份证号进行简单判断的正则表达式:[1-8][0-9]{5}(19|20)[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[0-9]{3}([0-9]|x)
关于15位的楼主可以自己试验下,不是很困难。

作者: z1342802487    时间: 2014-4-21 10:24
这个验证代码比较不好写。
1、首先验证前6位。参见《身份证号码前6位表示的地区一览表》看前6位是不和一览表相匹配。(1-6位)
2、出生年月日,检查闰年月份和日期。(7-14位)。15-17为顺序码,第17位奇数为男偶数为女。
3、18位校验位,前17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2.将这17位数字和对应系数相乘的结果相加除以11,余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。
2和3还能凑活写出来,第一项足以吓退99%的人。
希望能帮到你






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2