博 客 - 正文

身份证号码的编码规则及校验

分类:分享 wod 阅读(1011)

身份证号码的编码规则

身份证号码共18位,由17位本体码和1位校验码组成。

  1. 前6位是地址码,表示登记户口时所在地的行政区划代码,依照《中华人民共和国行政区划代码》国家标准(GB/T2260)的规定执行;

  2. 7到14位是出生年月日,采用YYYYMMDD格式;

  3. 15到17位是顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编订的顺序号,顺序码的奇数分配给男性,偶数分配给女性,即第17位奇数表示男性,偶数表示女性;

  4. 第18位是校验码,采用ISO 7064:1983, MOD 11-2校验字符系统,计算规则下一章节说明。


一代身份证与二代身份证的区别在于:

  1. 一代身份证是15位,二代身份证是18位;

  2. 一代身份证出生年月日采用YYMMDD格式,二代身份证出生年月日采用YYYYMMDD格式;

  3. 一代身份证无校验码,二代身份证有校验码。

校验码计算规则

身份证号码中各个位置上的号码字符值应满足下列公式的校验: i=118(ai×Wi)1(mod11)

  • i 表示号码字符从右至左包括校验码字符在内的位置序号;

  • ai 表示第i位置上的号码字符值, a1 是身份证号码第18位校验码;

  • Wi i位置上的加权因子,加权因子计算公式: Wi=2i1(mod11)

举例说明:

笔者身份证号码为370683198901117657,根据上述公式进行校验。

20221114_970057_v2-7480312fcdac7d9fad57e5026c6b0f1e_720w.png

i=118(ai×Wi)=3971(mod11)

大家可以根据此方法验证自己的身份证号码。


了解了身份证号码的校验公式后,根据同余定理可证得身份证号码校验码的计算公式:


v2-8185854ad5213e78e51746a8e9121db3_720w.png


当 a1 值等于10时,用罗马数字符X表示。此处需要注意:是罗马数字X,不应理解为英文字母X

实际应用

在金融行业软件系统中,对于身份证号码的采集、校验用途甚广。

  1. 身份证号码前6位,可采集客户户籍所在地,只需将国家标准GB/T 2260中定义的行政区划代码导入数据库,程序中进行映射即可;但需要注意的是,行政区划代码每隔几年会修订一次,从笔者手上的2007版来看,共经历了1982年、1984年、1986年、1988年、1991年、1995年、1999年、2002年、2007年九次修订,所以要预留更新机制;

  2. 身份证号码7到14位,可采集客户的出生日期、年龄、生日;

  3. 身份证号码17位,可采集客户的性别,奇数表示男性,偶数表示女性;

  4. 身份证号码的验证渠道,不管验证成功与否,往往都是收费的,比如银行渠道、公安部渠道,在发往这些渠道验证之前,先对其进行长度、正则表达式、校验码的验证,能够适当提高收费验证的成功率,节省成本支出;而且也可以提升用户体验,在用户输入错误时及时反馈而不必等待验证渠道结果的返回。

下面,就以实际代码为例,说明身份证号码校验的方法。首先,给出身份证号码的正则表达式:

/**
 * 检查是否为正确身份证
 *
 * @param $IDCard   string  身份证号码
 * @return bool
 */
function isIDCard(string $IDCard): bool
{
    $weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];//加权因子
    $cc = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];//校验码
    for($i=0;$i<strlen($IDCard)-1;$i++){
        $sum += $IDCard[$i] * $weight[$i];
    }
    $n = $sum%11;
    $a1 = strtolower($IDCard[17]);
    $a2 = strtolower($cc[$n]);
    if($a1 == $a2){
        return true;
    }else{
        return false;
    }
}


数据驱动未来

立即注册

客服微信

请打开手机微信,扫一扫联系我们

客服QQ
75608178

商务号,添加请说明来意

返回顶部