《PHP應用:PHP實現(xiàn)中國公民身份證號碼有效性驗證示例代碼》要點:
本文介紹了PHP應用:PHP實現(xiàn)中國公民身份證號碼有效性驗證示例代碼,希望對您有用。如果有疑問,可以聯(lián)系我們。
PHP應用本文將使用Java實現(xiàn)中國公民(15位或者18位)身份證號碼的相關驗證,功能如下:
PHP應用身份證號碼驗證
PHP應用1、號碼的結構 公民身份號碼是特征組合碼,由十七位數(shù)字本體碼和一位校驗碼組成.排列順序從左至右依次為:六位數(shù)字地址碼,八位數(shù)字出生日期碼,三位數(shù)字順序碼和一位數(shù)字校驗碼.
PHP應用2、地址碼(前六位數(shù))
PHP應用表示編碼對象常住戶口所在縣(市、旗、區(qū))的行政區(qū)劃代碼,按GB/T2260的規(guī)定執(zhí)行.
PHP應用3、出生日期碼(第七位至十四位)
PHP應用表示編碼對象出生的年、月、日,按GB/T7408的規(guī)定執(zhí)行,年、月、日代碼之間不用分隔符.
PHP應用4、順序碼(第十五位至十七位)
PHP應用表示在同一地址碼所標識的區(qū)域范圍內(nèi),對同年、同月、同日出生的人編定的順序號, 順序碼的奇數(shù)分配給男性,偶數(shù)分配給女性.
PHP應用5、校驗碼(第十八位數(shù))
PHP應用(1)十七位數(shù)字本體碼加權求和公式 S = Sum(Ai * Wi), i = 0, … , 16 ,先對前17位數(shù)字的權求和
PHP應用Ai:表示第i位置上的身份證號碼數(shù)字值
PHP應用Wi:表示第i位置上的加權因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
PHP應用(2)計算模 Y = mod(S, 11)
PHP應用(3)通過模得到對應的校驗碼 Y: 0 1 2 3 4 5 6 7 8 9 10 校驗碼: 1 0 X 9 8 7 6 5 4 3 2
PHP應用IDValidator.php
PHP應用
<?php
namespace com\jdk5\blog\IDValidator;
class IDValidator {
private static $GB2260;
private static $instance;
private static $cache = array();
private static $util;
function __construct() {
if (!class_exists("com\jdk5\blog\IDValidator\GB2260")){
include 'GB2260.php';
}
if (!class_exists("com\jdk5\blog\IDValidator\util")){
include 'util.php';
}
self::$GB2260 = GB2260::getGB2260 ();
self::$util = util::getInstance();
}
public static function getInstance() {
if (is_null ( self::$instance )) {
self::$instance = new IDValidator ();
}
return self::$instance;
}
function isValid($id) {
$code = self::$util->checkArg ( $id );
if ($code === false) {
return false;
}
// 查詢cache
if (isset ( self::$cache [ $id ] ) && self::$cache [$id] ['valid'] !== false) {
return self::$cache [$id] ['valid'];
} else {
if (! isset ( self::$cache [ $id ] )) {
self::$cache [$id] = array ();
}
}
$addr = substr ( $code ['body'], 0, 6 );
$birth = $code ['type'] === 18 ? substr ( $code ['body'], 6, 8 ) :
substr ( $code ['body'], 6, 6 );
$order = substr ( $code ['body'], - 3 );
if (! (self::$util->checkAddr ( $addr ) && self::$util->checkBirth ( $birth ) &&
self::$util->checkOrder ( $order ))) {
self::$cache [$id] ['valid'] = false;
return false;
}
// 15位不含校驗碼,到此已結束
if ($code ['type'] === 15) {
self::$cache [$id] ['valid'] = true;
return true;
}
/* 校驗位部分 */
// 位置加權
$posWeight = array ();
for($i = 18; $i > 1; $i --) {
$wei = self::$util->weight ( $i );
$posWeight [$i] = $wei;
}
// 累加body部分與位置加權的積
$bodySum = 0;
$bodyArr = str_split( $code ['body'] );
for($j = 0; $j < count ( $bodyArr ); $j ++) {
$bodySum += (intval ( $bodyArr [$j], 10 ) * $posWeight [18 - $j]);
}
// 得出校驗碼
$checkBit = 12 - ($bodySum % 11);
if ($checkBit == 10) {
$checkBit = 'X';
} else if ($checkBit > 10) {
$checkBit = $checkBit % 11;
}
// 檢查校驗碼
if ($checkBit != $code ['checkBit']) {
self::$cache [$id] ['valid'] = false;
return false;
} else {
self::$cache [$id] ['valid'] = true;
return true;
}
}
// 分析詳細信息
function getInfo ($id) {
// 號碼必須有效
if ($this->isValid($id) === false) {
return false;
}
// TODO 復用此部分
$code = self::$util->checkArg($id);
// 查詢cache
// 到此時通過isValid已經(jīng)有了cache記錄
if (isset(self::$cache[$id]) && isset(self::$cache[$id]['info'])) {
return self::$cache[$id]['info'];
}
$addr = substr($code['body'], 0, 6);
$birth = ($code['type'] === 18 ? substr($code['body'], 6, 8) :
substr($code['body'], 6, 6));
$order = substr($code['body'], -3);
$info = array();
$info['addrCode'] = $addr;
if (self::$GB2260 !== null) {
$info['addr'] = self::$util->getAddrInfo($addr);
}
$info ['birth'] = ($code ['type'] === 18 ? (substr ( $birth, 0, 4 ) . '-' . substr ( $birth, 4, 2 ) . '-' . substr ( $birth, - 2 )) : ('19' . substr ( $birth, 0, 2 ) . '-' . substr ( $birth, 2, 2 ) . '-' . substr ( $birth, - 2 )));
$info['sex'] = ($order % 2 === 0 ? 0 : 1);
$info['length'] = $code['type'];
if ($code['type'] === 18) {
$info['checkBit'] = $code['checkBit'];
}
// 記錄cache
self::$cache[$id]['info'] = $info;
return $info;
}
// 仿造一個號
function makeID ($isFifteen=false) {
// 地址碼
$addr = null;
if (self::$GB2260 !== null) {
$loopCnt = 0;
while ($addr === null) {
// 防止死循環(huán)
if ($loopCnt > 50) {
$addr = 110101;
break;
}
$prov = self::$util->str_pad(self::$util->rand(66), 2, '0');
$city = self::$util->str_pad(self::$util->rand(20), 2, '0');
$area = self::$util->str_pad(self::$util->rand(20), 2, '0');
$addrTest = $prov . $city . $area;
if (isset(self::$GB2260[$addrTest])) {
$addr = $addrTest;
break;
}
$loopCnt ++;
}
} else {
$addr = 110101;
}
// 出生年
$yr = self::$util->str_pad(self::$util->rand(99, 50), 2, '0');
$mo = self::$util->str_pad(self::$util->rand(12, 1), 2, '0');
$da = self::$util->str_pad(self::$util->rand(28, 1), 2, '0');
if ($isFifteen) {
return $addr . $yr . $mo . $da
. self::$util->str_pad(self::$util->rand(999, 1), 3, '1');
}
$yr = '19' . $yr;
$body = $addr . $yr . $mo . $da . self::$util->str_pad(self::$util->rand(999, 1), 3, '1');
// 位置加權
$posWeight = array();
for ($i = 18; $i > 1; $i--) {
$wei = self::$util->weight($i);
$posWeight[$i] = $wei;
}
// 累加body部分與位置加權的積
$bodySum = 0;
$bodyArr = str_split($body);
for ($j = 0; $j < count($bodyArr); $j++) {
$bodySum += (intval($bodyArr[$j], 10) * $posWeight[18 - $j]);
}
// 得出校驗碼
$checkBit = 12 - ($bodySum % 11);
if ($checkBit == 10) {
$checkBit = 'X';
} else if ($checkBit > 10) {
$checkBit = $checkBit % 11;
}
return ($body . $checkBit);
}
}
PHP應用調(diào)用
PHP應用
<?php
header("Content-type: text/html; charset=utf-8");
include 'IDValidator.php';
$v = com\jdk5\blog\IDValidator\IDValidator::getInstance();
//生成一個18位身份證號
$id = $v->makeID();
//獲取身份證信息
$info = $v->getInfo($id);
var_dump($info);
//生成一個15位身份證號
$id = $v->makeID(true);
$info = $v->getInfo($id);
var_dump($info);
//驗證身份證號是否正確
var_dump($v->isValid("123456789012345678"));
PHP應用以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持維易PHP.
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/868.html