Categories: PHP

[PHP] 身份證字號驗證 精簡版

工作需要要驗證身份證字號,不過網路上找到的版本沒辦法正確驗證

最後還是自己寫了一個 一般版精簡版

function pid_check($pid)
{   
    $iPidLen = strlen($pid);
    if(!preg_match("/^[A-Za-z][1-2][0-9]{8}$/",$pid) && $iPidLen != 10)
    {
        return FALSE;
    }
    $head = array("A"=>1,"B"=>0,"C"=>9,"D"=>8,"E"=>7,"F"=>6,"G"=>5,"H"=>4,"I"=>9,"J"=>3,"K"=>2,"M"=>1,"N"=>0,"O"=>8,"P"=>9,"Q"=>8,"T"=>5,"U"=>4,"V"=>3,"W"=>1,"X"=>3,"Z"=>0,"L"=>2,"R"=>7,"S"=>6,"Y"=>2);
    $pid  = strtoupper($pid);
    $iSum  = 0;
    for($i=0;$i<$iPidLen;$i++)
    {
        $sIndex = substr($pid,$i,1);
        $iSum   += (empty($i)) ? $head[$sIndex] : intval($sIndex) * abs( 9 - base_convert($i,10,9) );
    }
    return ( $iSum  % 10 == 0 ) ? TRUE:FALSE;
}

精簡版的意義就是 把 身份證字號的英文,直接轉換成 總數,接著 每個字元位置要分別乘以 1 9 8 7 6 5 4 3 2 1 1,省去了 1 & 9 就剩下 8 7 6 5 4 3 2 1 1

省去用陣列參照方式,把索引改為9進位模式, 遇到進位就變成 10 接著在 減掉 9 就是

9 - base_convert($i,10,9)

因為 9 – 10 所以 最後一個變成負的,在放個絕對值 函數 abs 就搞定…..

就可以這樣轉換

1 2 3 4 5 6 7 8 9
8 7 6 5 4 3 2 1 1

程式碼減少很多,不過會不會資源吃的更多呢 XD

另外也有其他種寫法,不用二進位

其實也可以不用用進位法表示

$point = (9-$i == 0) ? 9-$i : 1;

或是

$point = 9-$i;
if($point ==  0){$point++;}

最後一行改為

$iSum   += (empty($i)) ? $head[$sIndex] : intval($sIndex) * $point;

也是可以運作

另外謝謝 吳大雄 提示,英文參照表的部分,也可以直接省去十位數,只需要餘數就可以了

Mesak

我是米薩克,想了解更多可以點選  關於我 

Disqus Comments Loading...
Share
Published by
Mesak

Recent Posts

[教學] 利用 n8n 建立 LINE 聊天機器人

n8n 有多厲害,這邊就不贅述...

3 週 ago

[開箱] IROCKS K103R 熱插拔無線機械式鍵盤

許久沒有開箱了,近年鍵盤的規格...

3 個月 ago

[開箱] IROCKS-K85R 無線機械鍵盤

最近一直想要組一把 無線的 9...

1 年 ago

[開箱] IROCKS K75M 銀色上蓋機械式鍵盤

IROCKS K75M 這款鍵...

2 年 ago

[開箱] IROCKS M31E 粉紅色光學遊戲滑鼠

喜歡粉紅色周邊產品的朋友,有一...

2 年 ago