验证身份证号码的合法性
在网站上实现对身份证号码合法性的校验可以有效预防 PHP 脚本接收到注册表单传递过来的非法身份证号码。
中国(大陆)公民身份证号码每一位所代表的意义,网上很多文章都有介绍,在此就不赘述。其中身份证号码的最后一位是校验码,根据前 17 位计算得到。算法大概是这样:把前 17 位的每一个数字和一串加权因子相乘,再计算这些乘积的和;把这些乘积的和模 11 得到的数字作为序号,最后在一个校验码串中提取出与序号相对应的字符。当然,网上也有不少文章描述如何计算这个校验码,下面尝试用 PHP 脚本来完成这一工作。
假设某中国(大陆)公民的身份证号码前 17 位是:44010221990101001(注:此人出生于2199年)。根据上面的算法,代码应该是这样的:
<?php
运行以上代码之后,可以算出该身份证的校验码为 9 。
$body = '44010221990101001'; //身份证号码前 17 位,可以从各种数据源中获得(如数据库、用户提交的表单等)
$wi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); //加权因子
$ai = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'); //校验码串
for ($i = 0; $i < 17; $i ++) //按顺序循环处理前 17 位
{
$b = (int) $body{$i}; //提取前 17 位的其中一位,并将变量类型转为实数
$w = $wi[$i]; //提取相应的加权因子
$sigma += $b * $w; //把从身份证号码中提取的一位数字和加权因子相乘,并累加
}
$number = $sigma % 11; //计算序号
$check_number = $ai[$number]; //按照序号从校验码串中提取相应的字符
echo $body . $check_number; //输出
?>
在实际应用中可以把这段代码的一些语句合并,去除没必要的变量,优化得到如下代码:
<?php
本文原载旧版博客 2005 年 8 月 27 日。
$body = '44010221990101001';
$wi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
$ai = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
for ($i = 0; $i < 17; $i ++)
{
$sigma += ((int) $body{$i}) * $wi[$i];
}
echo $body . $ai[($sigma % 11)];
?>