18位身份證標准在國家質量技術監督局於1999年7月1日實施的gb11643-1999《公民身份號碼》中做了明確的規定。gb11643-1999《公民身份號碼》為gb11643-1989《社會保障號碼》的修訂版,其中指出將原標准名稱"社會保障號碼"更名為"公民身份號碼",另外gb11643-1999《公民身份號碼》從實施之日起代替gb11643-1989。
gb11643-1999《公民身份號碼》主要內容如下:
一、范圍
該標准規定了公民身份號碼的編碼對象、號碼的結構和表現形式,使每個編碼對象獲得一個唯一的、不變的法定號碼。
二、編碼對象
公民身份號碼的編碼對象是具有中華人民共和國國籍的公民。
三、號碼的結構和表示形式
1、號碼的結構
公民身份號碼是特征組合碼,由十七位數字本體碼和一位校驗碼組成。排列順序從左至右依次為:六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。
2、地址碼
表示編碼對象常住戶口所在縣(市、旗、區)的行政區划代碼,按gb/t2260的規定執行。
3、出生日期碼
表示編碼對象出生的年、月、日,按gb/t7408的規定執行,年、月、日代碼之間不用分隔符。
4、順序碼
表示在同一地址碼所標識的區域范圍內,對同年、同月、同日出生的人編定的順序號,順序碼的奇數分配給男性,偶數分配給女性。
5、校驗碼
(1)十七位數字本體碼加權求和公式
s = sum(ai * wi), i = 0, ... , 16 ,先對前17位數字的權求和
ai:表示第i位置上的身份證號碼數字值
wi:表示第i位置上的加權因子
wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)計算模
y = mod(s, 11)
(3)通過模得到對應的校驗碼
y: 0 1 2 3 4 5 6 7 8 9 10
校驗碼: 1 0 x 9 8 7 6 5 4 3 2
四、舉例如下:
北京市朝陽區: 11010519491231002x
廣東省汕頭市: 440524188001010014
15位的身份證編碼首先把出生年擴展為4位,簡單的就是增加一個19
<?php $a="440524188001010014"; $b=array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2); $sum=0; foreach($b as $k=>$v){ $sum += $v*$a[$k]; } echo $sum%11;
五、說明
1.程序可以根據已有的17位數字本體碼,獲取對應的驗證碼。
2.該程序可以剔除驗證碼不正確的身份證號碼。
3.15位的身份證出生年份采用年份后2位,沒有最后1位校驗碼。
4.完整的身份證18位,最后一位校驗位可能是非數字。我們的一個項目,數據庫保存前17位數字,這樣對應一些SQL語句(比如inner join)有加速作用的!!!