18位身份证号码最后一位校验码的计算方法

来源:互联网 发布:买的淘宝号安全吗 编辑:程序博客网 时间:2024/05/06 14:58

标签: 身份证 18位校验码原理 java oracle delphi sanoul


公民身份号码是一系列组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 
前六位的内容可以通过建立数据库存储相应信息,由于全国行政区划每年都在发生变化,需要经常更新。 

最后一位的校验码计算方法如下: 
(1)十七位数字本体码加权求和公式,先对前17位数字加权求和 
S = Sum(Ai×Wi), i = 0,1,2,...,16 
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) 
Y是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

 

Java:

public static char doVerify(String id_no);
    {
        char pszSrc[]=id_no.toCharArray();;
        int iS = 0;
        int iW[]={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char szVerCode[] = new char[]{'1','0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        int i;
        for(i=0;i<17;i++);
        {
            iS += (int);(pszSrc[i]-'0'); * iW[i];
        }
        int iY = iS%11;
        return szVerCode[iY];
    }

Oracle:

create or replace function identity_card18(id_no char) return char is
  Result char(18);
  Type myarray1 is table of number index by binary_integer;
  Type myarray2 is table of char index by binary_integer;
  Ax myarray1;
  Bx myarray2;
  I number(3);
  A number(12,0);
begin
  Ax(1) := 7;
  Ax(2) := 9;
  Ax(3) := 10;
  Ax(4) := 5;
  Ax(5) := 8;
  Ax(6) := 4;
  Ax(7) := 2;
  Ax(8) := 1;
  Ax(9) := 6;
  Ax(10) := 3;
  Ax(11) := 7;
  Ax(12) := 9;
  Ax(13) := 10;
  Ax(14) := 5;
  Ax(15) := 8;
  Ax(16) := 4;
  Ax(17) := 2;
  Bx(1) := '1';
  Bx(2) := '0';
  Bx(3) := 'X';
  Bx(4) := '9';
  Bx(5) := '8';
  Bx(6) := '7';
  Bx(7) := '6';
  Bx(8) := '5';
  Bx(9) := '4';
  Bx(10) := '3';
  Bx(11) := '2';
 
  Result := Trim(Substr(Trim(Id_No),1,17));
 
  If Length(Trim(Result)) = 15 then
    Result := substr(Result,1,6) || '19' || substr(Result,7,9);
  end if;
  
  If Length(Trim(Result)) = 17 then
    A := 0;
    for I in 1..Ax.count loop
      A := A + Ax(i) * to_number(Substr(Result,i,1));
    end loop;
    A := A mod 11;
    Result := Trim(Result) || Bx(A+1);

  else

    Result := '000000000000000000';
  end if;

  return(Result);
end identity_card18;

Delphi:

function Identity_card18(Id_no:String):String;
const
  Ax : Array[0..16] of Integer = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
  Bx : Array[0..10] of String = ('1','0','X','9','8','7','6','5','4','3','2');
var 
  I,A : Integer;
  S : String;
begin
  S := Trim(Id_No);
  A := 0;

  If Length(Trim(S)) = 15 then
    S := Copy(Trim(S),1,6) + '19' + Copy(Trim(S),7,9);

  If Length(Trim(S)) = 17 then
  Begin
    For I := 0 to 16 do
      A := A + Ax[i] * StrToInt(S[i+1]);
    S := Trim(S) + Bx[A mod 11];
  End Else
    S := '000000000000000000';

  Result := S;
end;