顯示廣告
隱藏 ✕
看板 Mesak
作者 mesak (Mesak)
標題
 [PHP] 身份證字號驗證 精簡版

時間 2012年11月30日 Fri. PM 01:10:03

部落格:
http://mesak.tw/?p=628


一般版本:
http://disp.cc/b/732-4HbV

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"=>10,"C"=>19,"D"=>28,"E"=>37,"F"=>46,"G"=>55,"H"=>64,"I"=>39,"J"=>73,"K"=>82,"M"=>11,"N"=>20,"O"=>48,"P"=>29,"Q"=>38,"T"=>65,"U"=>74,"V"=>83,"W"=>21,"X"=>3,"Z"=>30,"L"=>2,"R"=>47,"S"=>56,"Y"=>12);
	
$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;
}

省去第一二位 英文直接換算總數




























NameValue算式Total
A101 * 1 + 0 * 91
B111 * 1 + 1 * 910
C121 * 1 + 2 * 919
D131 * 1 + 3 * 928
E141 * 1 + 4 * 937
F151 * 1 + 5 * 946
G161 * 1 + 6 * 955
H171 * 1 + 7 * 964
I343 * 1 + 4 * 939
J181 * 1 + 8 * 973
K191 * 1 + 9 * 982
M212 * 1 + 1 * 911
N222 * 1 + 2 * 920
O353 * 1 + 5 * 948
P232 * 1 + 3 * 929
Q242 * 1 + 4 * 938
T272 * 1 + 7 * 965
U282 * 1 + 8 * 974
V292 * 1 + 9 * 983
W323 * 1 + 2 * 921
X303 * 1 + 0 * 93
Z333 * 1 + 3 * 930
L202 * 1 + 0 * 92
R252 * 1 + 5 * 947
S262 * 1 + 6 * 956
Y313 * 1 + 1 * 912



其實也可以不用用進位法表示
$point = (9-$i == 0) ? 9-$i : 1;
或是
$point = 9-$i;
if($point ==  0){$point++;}

intval($sIndex) * $point;

也是一種辦法,不過我覺得二進位表示比較好玩 XD

對照表也可以留下餘數,更省
--
※ 作者: mesak 時間: 2012-11-30 13:10:03
※ 編輯: mesak 時間: 2014-02-04 17:57:41
※ 看板: Mesak 文章推薦值: 0 目前人氣: 0 累積人氣: 344 
r)回覆 e)編輯 d)刪除 M)不收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇