中国[15位]公民身份证校验原理及代码

805 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的29天,点击查看活动详情

15位身份证号码已经不再使用,全国统一使用18位身份证号码。

15 位身份证的基本格式

15位身份证号码由6位行政区划代码和9位出生日期组成,其中:

  • 前6位行政区划代码表示身份证持有人所在地的行政区域。
  • 后9位出生日期表示身份证持有人的出生日期,格式为YYYYMMDD。

例如,一个15位身份证号码为13022119720605XXX,则:

  • 前6位130221表示该身份证持有人所在的行政区域为河北省秦皇岛市海港区。
  • 后9位19720601表示该身份证持有人的出生日期为1972年6月1日。

15 位身份证的弃用与 18 位身份证的启用

15位身份证号码于2010年1月1日弃用,从2010年1月1日起,全国统一使用18位身份证号码。在2010年1月1日之前,持有15位身份证号码的人仍可使用15位身份证号码。

在15位身份证号码弃用之前,公民可以通过换发身份证的方式由15位身份证号码更换为18位身份证号码。此外,部分地区也提供了通过升级软件的方式,在不换发身份证的情况下将15位身份证号码升级为18位身份证号码。

如果您持有15位身份证号码,可以联系当地的公安部门或身份证发放机构,了解有关换发身份证或升级身份证号码的相关信息。

18 位身份证与 15 位身份证的区别

另外,18位身份证号码与15位身份证号码的区别在于,18位身份证号码除了包含15位身份证号码中的信息之外,还包含额外的3位数字和1位校验码。这些额外的数字和校验码能够更好地保证身份证号码的正确性和唯一性。

例如,一个18位身份证号码为13022119720605XXXX,则:

  • 前6位130221表示该身份证持有人所在的行政区域为河北省秦皇岛市海港区。
  • 后9位19720601表示该身份证持有人的出生日期为1972年6月1日。
  • 后3位605和校验码X为额外添加的数字和校验码。

通过额外添加的3位数字和1位校验码,18位身份证号码能够更好地保证身份证号码的正确性和唯一性,避免因身份证号码的错误或重复造成的各种问题。

18 位身份证的后 3 位与校验码生成规则

在实际应用中,18位身份证号码的后3位数字通常不会直接按照某个特定规则计算得到。相反,18位身份证号码的后3位数字是由公安部门或身份证发放机构在发放身份证时自动生成的。如果您想要了解18位身份证号码的后3位数字是如何生成的,可以联系当地的公安部门或身份证发放机构,询问相关信息。

15 位身份证号码校验实现

对于15位身份证号码,其校验方法与18位身份证号码类似,都是利用前面的几位数字乘以一定的系数并相加得到校验码。

不同的是,15位身份证号码的系数为[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4],校验码的值为[1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]

在代码示例中,函数接收一个参数id,表示要检验的身份证号码。首先,函数会检查身份证号码的长度是否为15位或18位。如果是15位,则将身份证号码的前15位数字和系数相乘,并将乘积和相加;如果是18位,则将身份证号码的前17位数字和系数相乘,并将乘积和相加。

接下来,无论身份证号码是15位还是18位,都会计算余数,并根据余数的值来检验校验码是否正确。如果校验码正确,则返回True;否则返回False

def check_id_card(id_card):
    coefs_15 = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4]
    coefs_18 = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    checks = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
    if len(id_card) == 15:
        # 将身份证号码的前15位数字和系数相乘,并将乘积和相加
        total = sum([int(id_card[i]) * coefs_15[i] for i in range(15)])
    elif len(id_card) == 18:
        # 将身份证号码的前17位数字和系数相乘,并将乘积和相加
        total = sum([int(id_card[i]) * coefs_18[i] for i in range(17)])
    else:
        return False
    # 计算余数
    mod = total % 11
    # 检验校验码是否正确
    if checks[mod] == id_card[-1].upper():
        return True
    else:
        return False