德国身份证(Personalausweis)数据校验失效问题及解决方案咨询
德国身份证(Personalausweis)校验失效后的有效解决方案
原用于德国身份证校验的PHP函数已失效,原函数代码如下:
//Pruefnummer ueberpruefen function check_number($id, $checknumber) { $p = 7; $sum = 0; for($i=0; $i < strlen($id); $i++) { $char = $id{$i}; if($char >= '0' && $char <= '9') $int = intval($char); else $int = ord($char)-55; $sum += $int*$p; if($p==1) $p=7; else if($p==3) $p=1; else if($p==7) $p=3; } $last_number = substr(strval($sum), -1); return $last_number == $checknumber; }
问题根源
原函数的权重循环逻辑错误:德国身份证校验的权重序列应为固定的7,3,1依次对应前9位字符,但原函数的权重切换顺序导致权重错位,最终校验结果不符合官方规则。
有效校验方案
根据德国身份证官方校验规则,正确的校验流程如下:
- 身份证号共10位,前9位为主体字符,第10位是校验码
- 字符转换:数字直接保留数值;大写字母A-Z转换为10-35(A=10,B=11…Z=35)
- 按固定权重序列
[7,3,1,7,3,1,7,3,1],将每个转换后的值与对应权重相乘 - 计算所有乘积的总和,对10取余
- 若余数为0,校验码应为0;否则校验码为
10 - 余数
修正后的PHP校验函数
function validateGermanIdCard($idNumber) { // 校验身份证号长度合法性 if (strlen($idNumber) !== 10) { return false; } $idPart = substr($idNumber, 0, 9); $checkDigit = substr($idNumber, 9, 1); $weights = [7, 3, 1, 7, 3, 1, 7, 3, 1]; $sum = 0; for ($i = 0; $i < 9; $i++) { $char = $idPart[$i]; // 转换字符为数值,非法字符直接判定无效 if (ctype_digit($char)) { $value = intval($char); } elseif (ctype_upper($char)) { $value = ord($char) - 55; } else { return false; } $sum += $value * $weights[$i]; } $remainder = $sum % 10; $calculatedCheckDigit = $remainder === 0 ? 0 : 10 - $remainder; return strval($calculatedCheckDigit) === $checkDigit; }
使用示例
// 测试有效身份证号(示例) $validId = "AB123456789"; // 符合规则的有效号码 var_dump(validateGermanIdCard($validId)); // 输出bool(true) // 测试无效身份证号 $invalidId = "AB123456780"; var_dump(validateGermanIdCard($invalidId)); // 输出bool(false)
内容的提问来源于stack exchange,提问作者Ermal Baliu
相关产品推荐
相关产品推荐

