身份证号校验码算法
ISO 7064:1983 MOD 11-2 是一种国际标准的校验码算法,专为验证数字序列的准确性而设计,广泛应用于身份证号、银行账号等场景。其核心是通过加权求和与模运算生成校验码,以下是详细解析:
🔢 一、算法原理与步骤
1. 加权因子分配
固定权重序列:前17位数字分别乘以特定权重(从左至右):
[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
权重值通过公式 Wi=2i−1mod11计算得出,确保唯一性。
2. 加权求和
计算前17位数字与对应权重的乘积之和 S:
S=∑i=117(ai×Wi)
示例:身份证前17位
53010219200508011
的计算过程:5×7 + 3×9 + 0×10 + ... + 1×4 + 1×2 = 189
3. 取模运算
对总和 S进行模11运算,得到余数 T:
T=Smod11
示例:189mod11=2。
4. 生成校验码
余数 T映射到校验码表:
余数T
0
1
2
3
4
5
6
7
8
9
10
校验码
1
0
X
9
8
7
6
5
4
3
2
示例:余数
2
→ 校验码X
,完整身份证号为53010219200508011X
。
⚙️ 二、算法特性
错误检测能力
可识别单数字错误(如
5
输为8
)可检测相邻数字交换(如
12
输为21
)理论检错率超 99% 。
校验码意义
X
对应罗马数字 10,避免校验码超长(否则需双字符)校验时需统一大写
X
,小写x
无效 。
💻 三、代码实现(Python)
def calculate_check_code(id_17: str) -> str:weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]check_codes = "10X98765432"total = sum(int(id_17[i]) * weights[i] for i in range(17))return check_codes[total % 11]def verify_id(id_18: str) -> bool:return calculate_check_code(id_18[:17]) == id_18[-1].upper()
使用示例:
id_num = "53010219200508011X"
print(verify_id(id_num)) # 输出 True
⚠️ 四、注意事项
输入合法性
前17位必须全为数字,否则需预处理或报错。
大小写敏感
校验码
X
必须大写,验证前建议转换id_18 = id_18.upper()
。
国标依据
中国身份证标准 GB 11643-1999 明确采用此算法,替代旧版15位身份证 。
💎 总结
ISO 7064:1983 MOD 11-2 通过权重分配→求和→取模→映射四步,高效生成校验码。其数学严谨性保障了身份证、金融账号等场景的数据可靠性。实际开发中需注意输入校验与大小写处理,以兼容标准要求。