首先说一下身份证号码的规则:

    6    前六位 是所在的省县市的代码 看这里行政区划代码

    4    出生年份

    2    出生月份

    2    出生的日

    2    所在的区域的派出所编号

    1    奇-男  偶-女 例如:9 表示同年同月同日同区域的男生第五个

    1    校验位

下面说说校验位的计算

首先有个加权因子W,17位 身份证号码前17位分别和自己的加权因子 相乘再求和;sum = Σ(Ai*Wi)

$weighte_code = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];

将的到的sum值 除以 11 得到余数 (sum % 11) ;余数有 0 - 10 11种结果 对应11个校验码

$checked_code = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];

将对应的校验码和身份证最后一位进行比对判断身份证号码是否合法;

实现代码如下:

$idstr = '120103199705252017';
var_dump(check_id_card($idstr));

function check_id_card($id_number)
{
    //身份证号码规则  城市6 +  日期 8 派出所编号 + 2位 + 同年同月同日同派出所第几位出生(男奇数 女偶说) 最后一位 校验位
    // 身份证校验方法
    // 前17位 每位 和 加权因子 相乘 最后求和
    // 取余 11
    // 拿到对应的校验码
    $id_number = $id_number . '';
    $weighte_code = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; //加权因子
    $checked_code = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]; //校验码
    $sum = 0;
    for ($i = 0; $i < 17; $i++) {
        $sum += $id_number[$i] * $weighte_code[$i];
    }
    $check_num = $checked_code[$sum % 11];
    return $check_num == $id_number[17];

}