结构和形式

  1. 号码的结构
    公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
  2. 地址码
    表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
  3. 出生日期码
    表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
  4. 顺序码
    表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
  5. 校验码
    根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

地址码

  • 华北地区: 北京市|110000,天津市|120000,河北省|130000,山西省|140000,内蒙古自治区|150000
  • 东北地区: 辽宁省|210000,吉林省|220000,黑龙江省|230000
  • 华东地区: 上海市|310000,江苏省|320000,浙江省|330000,安徽省|340000,福建省|350000,江西省|360000,山东省|370000
  • 华中地区: 河南省|410000,湖北省|420000,湖南省|430000
  • 华南地区: 广东省|440000,广西壮族自治区|450000,海南省|460000
  • 西南地区: 四川省|510000,贵州省|520000,云南省|530000,西藏自治区|540000,重庆市|500000
  • 西北地区: 陕西省|610000,甘肃省|620000,青海省|630000,宁夏回族自治区|640000,新疆维吾尔自治区|650000
  • 特别地区:台湾地区(886)|710000,香港特别行政区(852)|810000,澳门特别行政区(853)|820000

计算方法

  1. 将身份证号码前面的17位数分别乘以对应的系数。从第一位到第十七位的系数分别为:
位数1234567891011121314151617
系数7910584216379105842
  1. 将这17位数字和系数相乘的结果相加。
  2. 用加出来和除以11,取余。
  3. 余数只可能有0~10这11个数字。其对应关系为:
余数012345678910
效验码10X98765432
  1. 通过上面得知,如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字x。

例如:某男性的身份证号码为【53010219200508011x】, 我们看看这个身份证是不是合法的身份证。
首先我们得出前17位的乘积和【(5x7)+(3x9)+(0x10)+(1x5)+(0x8)+(2x4)+(1x2)+(9x1)+(2x6)+(0x3)+(0x7)+(5x9)+(0x10)+(8x5)+(0x8)+(1x4)+(1x2)】是189,然后用189除以11得出的结果是189/11=17----2,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。

Java实现效验

public Boolean isValidId(String _id){
    char ids[] = _id.toCharArray();
    if(ids.length!=18) {System.out.println("位数错误");return;}
    int modulus[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    char residue[] = {'1','0','X','9','8','7','6','5','4','3','2'};
    int sumId=0;
    for(int i=0;i<17;i++)
        sumId+=Integer.parseInt(String.valueOf(ids[i]))*modulus[i];
    if(residue[sumId%11]==ids[17]) System.out.println("效验成功");
    else System.out.println("效验失败");
}

C#实现效验

public void isValidId(string _id){
    char [] ids = _id.ToCharArray();
    if(ids.Length!=18) {Console.WriteLine("位数错误");return;}
    int []  modulus = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
      char [] residue = {'1','0','X','9','8','7','6','5','4','3','2'};
       int sumId=0;
       for(int i=0;i<17;i++)
        sumId+=int.Parse(ids[i].ToString())*modulus[i];
       if(residue[sumId%11]==ids[17]) Console.WriteLine("效验成功");
    else Console.WriteLine("效验失败");
}

PHP实现效验

function isValidId ($_id)
{
    $ids=str_split($_id);
    if(sizeof($ids)!=18) {echo "位数错误";return;}
    $modulus =Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
    $residue =Array('1','0','X','9','8','7','6','5','4','3','2');
    $sumId=0;
    for($i=0;$i<17;$i++){
        $sumId +=intval($ids[$i])*$modulus[$i];
    } 
    if($residue[$sumId%11]==$ids[17]) echo "效验成功";
    else echo "效验失败";
} 

Excel实现效验

=IF(LEN(A1)=0,"空",IF(LEN(A1)=15,"老号",IF(LEN(A1)<>18,"位数不对",IF(CHOOSE(MOD(SUM(MID(A1,1,1)*7+MID(A1,2,1)*9+MID(A1,3,1)*10+MID(A1,4,1)*5+MID(A1,5,1)*8+MID(A1,6,1)*4+MID(A1,7,1)*2+MID(A1,8,1)*1+MID(A1,9,1)*6+MID(A1,10,1)*3+MID(A1,11,1)*7+MID(A1,12,1)*9+MID(A1,13,1)*10+MID(A1,14,1)*5+MID(A1,15,1)*8+MID(A1,16,1)*4+MID(A1,17,1)*2),11)+1,1,0,"X",9,8,7,6,5,4,3,2)= IF(ISNUMBER(RIGHT(A1,1)*1),RIGHT(A1,1)*1,"X"),"正确","错误"))))
//A1为身份证号码所在单元格