身分証明書のコード規則

4332 ワード

原文:https://www.fanhaobai.com/2017/08/id-card.html
中国の現行の身分証明書システムには15人と18人の2種類の身分証明書番号があり、第1世代の身分証明書の多くは15人の番号であり、15人の身分証明書は1900.01.01から1999.12.31生まれの人コード(千年虫問題)しかないため、その後、18人の身分証明書番号に徐々に置き換えられた.

コーディング規則


15ビット


15ビットの身分証明書のコード規則は:DDDDDD YYYMMDD XXXS
各構成要素の説明:
セクション名
説明
DDDDDD
6ビット地域コード
YYMMDD
生年月日年を2桁で表す
XXS
シーケンスコード.このうちSは性別識別コードであり、奇数は男性であり、偶数は女性である.
例えば、ある15ビットIDは、513701930509101である.

18ビット


18人の身分証明書は15人の身分証明書より生年月日が8人に変更され、検査ビットが導入された.コードルール:DDDDDD YYYYYYMMDD XXX Y
各構成要素の説明:
セクション名
説明
DDDDDD
6ビット地域コード
YYYYMMDD
生年月日年を4桁で表す
XXX
シーケンスコード.奇数は男、偶数は女
Y
チェックビット.上位17ビット値の計算
検査ビットYの値範囲は[1,0,X,9,8,7,6,5,4,3,2]であり、これは重み付け方式で検査され、検査規則はp=mod(Σ(Ai)である.×Wi), 11)
パラメータの説明:
  • iは身分証明書の数字がある桁数で、1-17です.
  • Aiは身分証明書第i位に対応するデジタル値である.
  • Wiは重み付け因子であり、値は[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]である.
  • pは、Y範囲値を取得したp+1番目の値を検査値Yとする.

  • 例えば、ある18ビットIDビット:51370119305091010であり、検証ビットはその後計算される.

    フォーマットチェツク


    身分証明書の符号化規則を解析することにより,正規表現を用いてマッチングする身分証明書の検証規則を導くことができる.

    15ビット


    15ビットID DDDDDD YYMMDD XXSの各セクションの正規一致式は、次のとおりです.
    セクション名
    正規表現
    DDDDDD
    [1-9]\d{5}
    YYMMDD
    (\d{2})(0[1-9]|(1[0-2]))(([0-2][1-9])|([1-2]0)|31)
    XXS
    \d{3}
    これにより、15ビットの身分証明書の正規一致式が得られます.
    '^[1-9]\d{5}\d{2}(0[1-9]|(1[0-2]))(([0-2][1-9])|([1-2]0)|31)\d{3}$'
    // :
    '^[1-9]\d{7}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)\d{3}$'
    

    PHPでは次のようにチェックされます.
    const ID_15_PREG = '/^[1-9]\d{7}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)\d{3}$/';
    
    public static function validate($id)
    {
        if (!is_string($id) || empty($id)) {
            return false;
        } else if (strlen($id) == 15 && preg_match(static::ID_15_PREG, $id)) {
            return true;
        }
        return false;
    }
    

    18ビット


    同様に、18ビットの身分証明書DDDDDD YYYYMMDD XXX Yの各部分の正規一致式は、以下のとおりである.
    セクション名
    正規表現
    DDDDDD
    [1-9]\d{5}
    YYYYMMDD
    ([1-9]\d{3})(0[1-9]|(1[0-2]))(([0-2][1-9])|([1-2]0)|31)
    XXX
    \d{3}
    Y
    \d
    これにより、18ビットの身分証明書の正規一致式が得られます.
    '^[1-9]\d{5}([1-9]\d{3})((0[1-9]|(1[0-2]))(([0-2][1-9])|([1-2]0)|31)\d{3}\d|[Xx]$'
    // :
    '^[1-9]\d{5}[1-9]\d{3}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)(\d{4}|\d{3}[Xx])$'
    

    検査ビットの検査規則に基づいて、検査ビットの符号化を実現する:
    public static function getCheckBit($id)
    {
        if (18 !== strlen($id)) {
            return false;
        }
        $yArr = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
        $wArr = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        $sum = 0;
        for ($i = strlen($id)-2; $i>=0; $i--) {
            $sum += $id[$i] * $wArr[$i];
        }
        $key = $sum % 11;
        return $yArr[$key];
    }
    

    したがって、PHPにおける検証ロジックは、
    const ID_18_PREG = '/^[1-9]\d{5}[1-9]\d{3}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)(\d{4}|\d{3}[Xx])$/';
    
    public static function validate($id)
    {
        if (!is_string($id) || empty($id)) {
            return false;
        } else if (strlen($id) == 18 && preg_match(static::ID_18_PREG, $id) && strtoupper($id[17]) === self::getCheckBit($id)) {
           return true;
        } else if (strlen($id) == 15 && preg_match(static::ID_15_PREG, $id)) {
            return true;
        }
        return false;
    }
    

    15ビットから18ビットへの変換


    金融などの特殊な業界では、15人の身分証明書番号を18人にフォーマットする必要があります.15人の身分証明書の発行年はすべて19**年なので、18人になったときに生年月日を補充するときに直接19を追加すればいいです.
    変換手順:
  • 年に4桁に補完し、年前に直接19を追加した.
  • 補完アップステップの新しい番号は18ビットで、元の番号の末尾に直接Xを追加することができます.
  • 新しい番号の検証ビットを計算し、元の検証ビット値を置き換える.

  • 15ビットのIDが18ビットに変換されたコードは次のとおりです.
    public static function format18($id)
    {
        if (!static::validate($id)) {
            return '';
        } else if (15 !== strlen($id)) {
            return $id;
        }
        $newId = substr($id, 0, 6) . '19' . substr($id, -9) . 'X';
        $newId[17] = static::getCheckBit($newId);
        return $newId;
    }
    

    変換例の結果:
    //15 ---------------------18 
    '370725881105149' => '37072519881105149X'