JSP+Ajax+文本操作全选框实例 - -| 回首页 | 2006年索引 | - -转帖:从javascript语言本身谈项目实战

身份证校验码(JS,PHP,JSP验证)

关键词身份证    php    javascript    jsp                                          

身份证从15位升级至18位,我们知道有两位数据是在年份前面加上19,后面一位就是校验码。下面这个程序就是用来检验身份证升级至18位数的有效性的。分别用JavaScript,PHP,JSP做了效果。

源代码下载(含PHP,JSP,JS):http://jarryli.googlepages.com/checkIdentity.rar
演示地址:http://jarryli.googlepages.com/checkIdentity.html

校验方法:
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

(2)计算模
Y = mod(S, 11)

(3)通过模得到对应的校验码
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
回答者: 55SS22ZZ88CC - 高级经理 七级 3-3 17:02

身份证校验码生成算法

根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。……顺序码的奇数分给男性,偶数分给女性。校验码 是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

先引入公式:
∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1)

"*" 表示乘号
i--------表示身份证号码每一位的序号,从右至左,最左侧为18,最右侧为1。
a[i]-----表示身份证号码第 i 位上的号码
W[i]-----表示第 i 位上的权值 W[i] = 2^(i-1) mod 11
计算公式 (1) 令结果为 R

根据下表找出 R 对应的校验码即为要求身份证号码的校验码C。
R 0 1 2 3 4 5 6 7 8 9 10
C 1 0 X 9 8 7 6 5 4 3 2
由此看出 X 就是 10,罗马数字中的 10 就是 X


JSP源代码如下:


<%@ page contentType="text/html; charset=GBK" language="java" import="java.sql.*" errorPage="" pageEncoding="GBK"%>
<%
//set Chinese Char

//homepage:jiarry.126.com
request.setCharacterEncoding("GBK");
response.setCharacterEncoding("GBK");
response.setContentType("text/html; charset=GBK");
%>
<%
/*
身份证15升级18位以及最后一位的校验码
bolg:http://jiarry.blogchina.com;
1,∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1) ;
2,加权因子分别为 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
3,将前17位号码分别乘以各自的加权因子,再求和除以11,再取余数。
4,用余数对应下方的校验码
5,Y余数:  0 1 2 3 4 5 6 7 8 9 10 ;
6,校验码: 1 0 X 9 8 7 6 5 4 3 2 ;
*/

String[] ai=new String[17];
//用户的身份证号码数组;
int[] wi=new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
//17位数对应的加权因子,自左至右;
int[] yi=new int[]{0,1,2,3,4,5,6,7,8,9,10};
//余数;
String[] vi={"1","0","X","9","8","7","6","5","4","3","2"};
//余数对应的校验码;

%>
<%!
String[] ai=new String[17];
//用户的身份证号码数组;
int[] wi=new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
//17位数对应的加权因子,自左至右;
int[] yi=new int[]{0,1,2,3,4,5,6,7,8,9,10};
//余数;
String[] vi={"1","0","X","9","8","7","6","5","4","3","2"};
//余数对应的校验码;

public String getStrCn(String str)
{
     try{
        String temp_p=str;
        byte[] temp_t=temp_p.getBytes("ISO-8859-1");
        String temp=new String(temp_t,"GBK");
        return temp;
    }catch(Exception e){    }
    return "null";
}

//check type is number,return true or false;
public static boolean IsNum(String str)
{
 for(int i=0;i<str.length();i++)
 {
  if(str.charAt(i)<'0' || str.charAt(i)>'9')
   return false;
 }
 return true;
}


String msg15error="";int sum=0;int y;String v;

public String upto18(String obj){ 
     if(IsNum(obj) && obj.length()==15){
        msg15error="";
        String num17=obj.substring(0,6)+"19"+obj.substring(6,15);
        String getv=getVerify(num17);
        return num17+getv;
        //return v;
     }else{   
       msg15error="您输入的不是15位数字";
       return obj;
     }
    
}

public boolean checkVerify(String obj){
     obj=obj.toLowerCase();    
     if(obj.length()==18){
            String n17=obj.substring(0,17);
            String endNum=obj.substring(17,18);        
            if( IsNum(obj) || ( IsNum(obj.substring(0,17)) &&  endNum.equals("x") )){
            //如果检查的是18为整数,或者前17位是整数未位是x;
               String ay=getVerify(n17);
               if(ay.equals(endNum)){//如果得到的检验码与未位相符合刚返回true;否则都返回false;
                return true;
             }else{
                return false;
           }        
           
          }else{         
            return false;
         }        
    }else{
      return false;
  }
}

public String getVerify(String num17){
     sum=0;
     if(!IsNum(num17) || num17.length()!=17)
     {
      return "不是17个数字";
      }else{     
     
         for(int i=0;i<num17.length();i++){
             sum+=Integer.parseInt(String.valueOf(num17.charAt(i)))*wi[i];
         }
         y=sum%11;v=vi[y];
         return String.valueOf(v);
     }
}
%>
<style>
*{font-family:arial;font-size:100%;line-height:150%}
font{color:red}
</style>

<%
String number15="";String number18="";String verify="";
if(request.getParameter("number15")!=null)number15=request.getParameter("number15");
if(request.getParameter("number18")!=null)number18=request.getParameter("number18");
if(request.getParameter("verify")!=null)verify=request.getParameter("verify");

if(!number15.equals("") && number15.length()==15)
{
out.print(upto18(number15));
 number18=upto18(number15);
}
%>
<form name="check">
15位身份证:<input type="text" maxlength="15" name="number15" value="<%=number15%>"><font id="number15_info"><%=msg15error%></font><br>
<input type="submit" value="Update number to 18" ><br><br>
18位身份证:<input type="text" maxlength="18" name="number18" value="<%=number18%>"><font id="number18_info"></font><br>
检验结果:<font id="verify_info"><%if(!number18.equals(""))out.print(checkVerify(number18));%></font><br>
正确的校验码为:<input type="text" readonly name="verify"  value="<% if(number18.length()==18) out.print(getVerify(number18.substring(0,17)));%>"><br>
<input type="submit" value="Check Identity"  "><br>
</form>

JS源代码如下:



<style>
*{font-family:arial;font-size:100%;line-height:150%}
font{color:red}
</style>
<pre>
身份证15升级18位以及最后一位的校验码
1,∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1) ;
2,加权因子分别为 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
3,将前17位号码分别乘以各自的加权因子,再求和除以11,再取余数。
4,用余数对应下方的校验码
5,Y余数:  0 1 2 3 4 5 6 7 8 9 10 ;
6,校验码: 1 0 X 9 8 7 6 5 4 3 2 ;
</pre>
<form name="check">
15位身份证:<input type="text" maxlength="15" name="number15"><font id="number15_info"></font><br>
<input type="button" value="Update number to 18" onclick="updateNumber(this.form.number15)"><br><br>
18位身份证:<input type="text" maxlength="18" name="number18"><font id="number18_info"></font><br>
检验结果:<font id="verify_info"></font><br>
最后一位校验码为:<input type="text" readonly name="verify" ><br>
<input type="button" value="Check Identity"  onclick="checkVerify(this.form.number18)"><br>
</form>
<script type="text/javascript">
/*
身份证15升级18位以及最后一位的校验码
bolg:http://jiarry.blogchina.com;
1,∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1) ;
2,加权因子分别为 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
3,将前17位号码分别乘以各自的加权因子,再求和除以11,再取余数。
4,用余数对应下方的校验码
5,Y余数:  0 1 2 3 4 5 6 7 8 9 10 ;
6,校验码: 1 0 X 9 8 7 6 5 4 3 2 ;
*/

var ai=new Array();
//用户的身份证号码数组;

var wi=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];
//17位数对应的加权因子,自左至右;

var yi=[0,1,2,3,4,5,6,7,8,9,10];
//余数;

var vi=["1","0","X","9","8","7","6","5","4","3","2"];
//余数对应的校验码;

//
var number15_info=document.getElementById("number15_info");
var number18_info=document.getElementById("number18_info");
var verify_info=document.getElementById("verify_info");
//


function updateNumber(obj){
// var valid=false;
 var v=obj.value;
 if(isNaN(obj.value) || v.length!=15){
    alert("请输入15位身份证数字");obj.focus();return;
  }
  v=v.substr(0,6)+"19"+v.substr(6,9);
  getVerifyCode(v); 
  v=v+""+r;
  number15_info.innerHTML="升级成18位将是:"+v;
  document.check.number18.value=v;
  document.check.verify.value=r;
}

var msg;
var r;//最终的校验码;
var sum;
var y;
function getVerifyCode(num){//17位的号码请求,则可以返回检验码;

  msg="";r=0;y=0;sum=0;
  var v=num;v=v.toUpperCase();var vl;
  if(v.length==18)
      vl=v.length-1;
  else
      vl=v.length;
  if(vl!=17)
   {
   alert("请求号码不正确");return;
   }
     for(var i=0;i<vl;i++){
        ai[i]=v.charAt(i); 
        msg+=("数组"+i+", ai["+ai[i]+"]*wi["+wi[i]+"]="+ai[i]*wi[i]+"\n");  
        sum+=ai[i]*wi[i];//身份证号码分别乘以加权因子再求和; 
     }
     y=sum%11;    
     r=vi[y];//校验码中的第y个即时校验码;
     return r;

}

function checkVerify(o){
 var v=o.value;
 var n17=v.substring(0,17);
 //var valid=false;
 var num17 = v.substr(17,1);
 if(v.length!=18){
  alert("请输入18位身份证号码");o.focus();return;
 }else if(!isNaN(v)){
    //valid=true;
   //alert("18位全是数字");
 }else if( num17.toUpperCase() == "X" && !isNaN(n17)){
    //valid=true;
    //alert("第18位数字是X,前17位是数字");
 }else{
    alert("请输入有效的身份证号码");o.focus();return;
 }


 
getVerifyCode(v);

    alert("刚输入的号码为ai[i],"+
       "\n加权因子为wi[i],\n"+
       "ai[i]分别乘以wi[i]再相加的总和为sum\n"+
       "总和除以11得到余数Y\n"+
       "余数Y对应的校验码数字即时校验码\n"+
       msg+"\n总合为:"+sum+
       "\n总和除11取模(sum%11)得Y ="+y+
       "\n Y对应的校验码是:"+r);
      
       var verify_text="您输入的最后一位是 "+ num17 +" 错误,正确的应为 "+r;
       if(r== num17 )verify_text="恭喜您,最后一位校验码正确";
       verify_info.innerHTML=verify_text;
       document.check.verify.value=" "+r;
}
</script>



PHP源代码如下:


<style>
*{font-family:arial;font-size:100%;line-height:150%}
font{color:red}
</style>
<?php
/*
身份证15升级18位以及最后一位的校验码
bolg:http://jiarry.blogchina.com;
1,∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1) ;
2,加权因子分别为 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
3,将前17位号码分别乘以各自的加权因子,再求和除以11,再取余数。
4,用余数对应下方的校验码
5,Y余数:  0 1 2 3 4 5 6 7 8 9 10 ;
6,校验码: 1 0 X 9 8 7 6 5 4 3 2 ;
*/

$n15="";$n18="";$verify="";
if(isset($_GET["number15"]))$n15=$_GET["number15"];
if(isset($_GET["number18"]))$n18=$_GET["number18"];
if(isset($_GET["verify"]))$verify=$_GET["verify"];


$ai=array();//用户的身份证号码数组;

$wi=array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);//17位数对应的加权因子,自左至右;

$yi=array(0,1,2,3,4,5,6,7,8,9,10);//余数;

$vi=array("1","0","X","9","8","7","6","5","4","3","2");//余数对应的校验码;

function update18($num){
     if(strlen($num)<15)
     {
      return "不够15位";
     }
     else if(!is_numeric($num)){//is_int,is_numeric
      return "no number";
     }else{
     //$c="<b>19</b>";
     $c="19";
     $num=substr($num,0,6).$c.substr($num,6,9); 
     updateTo18($num);   
     return $num;
    }
 }
function updateTo18($obj){
 //传17位的数字可得到最后一位校验码;
global $ai;global $wi;global $yi;global $vi;global $n18;
 
$sum=0;$y;

 if(strlen($obj)==17)
  {    
     for($i=0;$i<count($wi);$i++){
          //$ai[$i]=substr($obj,$i,1);$sum=$sum+$ai[$i]*$wi[$i];
            $sum+=substr($obj,$i,1)* $wi[$i];//这种方式更简洁;
        }
        $y=$vi[$sum%11];
        //echo $y;
        $n18=$obj.$y;
        echo $n18;
   } 
}
function checkVerify($o){
global $ai;global $wi;global $yi;global $vi;

$sum=0;
     for($i=0;$i<count($wi);$i++){
            $sum+=substr($o,$i,1)* $wi[$i];//这种方式更简洁;
        }
        echo "总数".$sum." ";
        $y=$vi[$sum%11];
     if($y == substr($o,17,1))
     {
       echo "验证码正确".$y;
     }else{
        echo "验证明错误".$y;
     }
}
?>
<pre>
身份证15升级18位以及最后一位的校验码
1,∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1) ;
2,加权因子分别为 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
3,将前17位号码分别乘以各自的加权因子,再求和除以11,再取余数。
4,用余数对应下方的校验码
5,Y余数:  0 1 2 3 4 5 6 7 8 9 10 ;
6,校验码: 1 0 X 9 8 7 6 5 4 3 2 ;
</pre>
<form name="check">
15位身份证:<input type="text" maxlength="15" name="number15" value="
<?php
global $n15;
echo $n15;
?>
"><font id="number15_info"></font><br>
<input type="submit" value="Update number to 18" ><br><br>
18位身份证:<input type="text" maxlength="18" name="number18" value="
<?php
 if(strlen($n15)>1)
 update18($n15);
else
 echo $n18;
?>" ><font id="number18_info"></font><br>
检验结果:<font id="verify_info"></font><br>
最后一位校验码为:<input type="text" readonly name="verify" value="
<?php
checkVerify($n18);
?>" ><br>
<input type="submit" value="Check Identity" ><br>
</form>
<?php

update18($n15);

?>



【作者: 皮子/Jarry/Jiarry】【访问统计:】【2006年09月4日 星期一 21:13】【 加入博采】【打印

Trackback

你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=5616623

回复

验证码:   
评论内容: