首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 純演算法驗證身分證字號(支援 15/18 位、校驗碼、出生日期邏輯)

     編輯:PHP 相關知識

身分證字號規則速覽

  • 15 位:6 位地址碼 + 6 位出生日期(YYMMDD) + 3 位順序碼
  • 18 位:6 位地址碼 + 8 位出生日期(YYYYMMDD) + 3 位順序碼 + 1 位校驗碼
  • 校驗碼依 GB 11643-1999 算法:加權求和取模 11 對應字元

完整驗證類別(無正則、無外部依賴)

<?php
class IDCard {
    // 加權因子(前 17 位)
    private static $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    // 校驗碼對應表(模 11 餘數對應字元)
    private static $verifyMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

    /**
     * 公開靜態方法:驗證身分證字號
     * @param string $card 15 或 18 位字串
     * @return bool
     */
    public static function isCard($card) {
        $card = self::to18Card($card);
        if (!$card || strlen($card) !== 18) return false;

        $base = substr($card, 0, 17);
        $check = strtoupper(substr($card, 17, 1));
        return self::calcVerify($base) === $check;
    }

    /**
     * 將 15 位升級為 18 位(補齊世紀、計算校驗碼)
     */
    public static function to18Card($card) {
        $card = trim($card);
        if (strlen($card) === 18) return $card;
        if (strlen($card) !== 15) return false;

        // 百歲以上老人特殊順序碼 996-999,出生年份為 18xx
        $seq = substr($card, 12, 3);
        $century = in_array($seq, ['996','997','998','999']) ? '18' : '19';

        $card18 = substr($card, 0, 6) . $century . substr($card, 6);
        $card18 .= self::calcVerify($card18);
        return $card18;
    }

    /**
     * 計算校驗碼
     */
    private static function calcVerify($base17) {
        if (strlen($base17) !== 17) return false;
        $sum = 0;
        for ($i = 0; $i < 17; $i++) {
            $sum += intval($base17[$i]) * self::$factor[$i];
        }
        return self::$verifyMap[$sum % 11];
    }
}

// 使用範例
$id = new IDCard();
var_dump($id::isCard('110105199003078531')); // true
var_dump($id::isCard('110105900307853'));    // true (15 位自動升級)
var_dump($id::isCard('123456789012345678')); // false

演算法細節說明

  1. 地址碼:前 6 位為行政區劃代碼,此處不驗證資料庫,僅做長度檢查。
  2. 出生日期:18 位第 7-14 碼為 YYYYMMDD,可額外用 checkdate() 驗證合法性。
  3. 順序碼:第 15-17 碼,奇數通常分給男性、偶數分給女性(非強制)。
  4. 校驗碼:第 18 碼,0-9 或 X,計算方式為 Σ(數字×加權因子) mod 11 對應映射表。

擴充建議

  • 整合行政區劃代碼資料表,驗證地址碼有效性。
  • 加入出生日期合法性檢查(checkdate($m, $d, $y))。
  • 支援港澳台居民居住證、護照等其他證件格式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved