PHP實(shí)現(xiàn)中國(guó)公民身份證號(hào)碼有效性驗(yàn)證示例代碼
本文將使用Java實(shí)現(xiàn)中國(guó)公民(15位或者18位)身份證號(hào)碼的相關(guān)驗(yàn)證,功能如下:
- 身份證號(hào)有效性驗(yàn)證
- 分析詳細(xì)身份證信息
- 生成一個(gè)虛擬的省份證號(hào)碼。
身份證號(hào)碼驗(yàn)證
1、號(hào)碼的結(jié)構(gòu) 公民身份號(hào)碼是特征組合碼,由十七位數(shù)字本體碼和一位校驗(yàn)碼組成。排列順序從左至右依次為:六位數(shù)字地址碼,八位數(shù)字出生日期碼,三位數(shù)字順序碼和一位數(shù)字校驗(yàn)碼。
2、地址碼(前六位數(shù))
表示編碼對(duì)象常住戶(hù)口所在縣(市、旗、區(qū))的行政區(qū)劃代碼,按GB/T2260的規(guī)定執(zhí)行。
3、出生日期碼(第七位至十四位)
表示編碼對(duì)象出生的年、月、日,按GB/T7408的規(guī)定執(zhí)行,年、月、日代碼之間不用分隔符。
4、順序碼(第十五位至十七位)
表示在同一地址碼所標(biāo)識(shí)的區(qū)域范圍內(nèi),對(duì)同年、同月、同日出生的人編定的順序號(hào), 順序碼的奇數(shù)分配給男性,偶數(shù)分配給女性。
5、校驗(yàn)碼(第十八位數(shù))
(1)十七位數(shù)字本體碼加權(quán)求和公式 S = Sum(Ai * Wi), i = 0, … , 16 ,先對(duì)前17位數(shù)字的權(quán)求和
Ai:表示第i位置上的身份證號(hào)碼數(shù)字值
Wi:表示第i位置上的加權(quán)因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)計(jì)算模 Y = mod(S, 11)
(3)通過(guò)模得到對(duì)應(yīng)的校驗(yàn)碼 Y: 0 1 2 3 4 5 6 7 8 9 10 校驗(yàn)碼: 1 0 X 9 8 7 6 5 4 3 2
IDValidator.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;
}
// 查詢(xún)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位不含校驗(yàn)碼,到此已結(jié)束
if ($code ['type'] === 15) {
self::$cache [$id] ['valid'] = true;
return true;
}
/* 校驗(yàn)位部分 */
// 位置加權(quán)
$posWeight = array ();
for($i = 18; $i > 1; $i --) {
$wei = self::$util->weight ( $i );
$posWeight [$i] = $wei;
}
// 累加body部分與位置加權(quán)的積
$bodySum = 0;
$bodyArr = str_split( $code ['body'] );
for($j = 0; $j < count ( $bodyArr ); $j ++) {
$bodySum += (intval ( $bodyArr [$j], 10 ) * $posWeight [18 - $j]);
}
// 得出校驗(yàn)碼
$checkBit = 12 - ($bodySum % 11);
if ($checkBit == 10) {
$checkBit = 'X';
} else if ($checkBit > 10) {
$checkBit = $checkBit % 11;
}
// 檢查校驗(yàn)碼
if ($checkBit != $code ['checkBit']) {
self::$cache [$id] ['valid'] = false;
return false;
} else {
self::$cache [$id] ['valid'] = true;
return true;
}
}
// 分析詳細(xì)信息
function getInfo ($id) {
// 號(hào)碼必須有效
if ($this->isValid($id) === false) {
return false;
}
// TODO 復(fù)用此部分
$code = self::$util->checkArg($id);
// 查詢(xún)cache
// 到此時(shí)通過(guò)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;
}
// 仿造一個(gè)號(hào)
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');
// 位置加權(quán)
$posWeight = array();
for ($i = 18; $i > 1; $i--) {
$wei = self::$util->weight($i);
$posWeight[$i] = $wei;
}
// 累加body部分與位置加權(quán)的積
$bodySum = 0;
$bodyArr = str_split($body);
for ($j = 0; $j < count($bodyArr); $j++) {
$bodySum += (intval($bodyArr[$j], 10) * $posWeight[18 - $j]);
}
// 得出校驗(yàn)碼
$checkBit = 12 - ($bodySum % 11);
if ($checkBit == 10) {
$checkBit = 'X';
} else if ($checkBit > 10) {
$checkBit = $checkBit % 11;
}
return ($body . $checkBit);
}
}
調(diào)用
<?php
header("Content-type: text/html; charset=utf-8");
include 'IDValidator.php';
$v = com\jdk5\blog\IDValidator\IDValidator::getInstance();
//生成一個(gè)18位身份證號(hào)
$id = $v->makeID();
//獲取身份證信息
$info = $v->getInfo($id);
var_dump($info);
//生成一個(gè)15位身份證號(hào)
$id = $v->makeID(true);
$info = $v->getInfo($id);
var_dump($info);
//驗(yàn)證身份證號(hào)是否正確
var_dump($v->isValid("123456789012345678"));
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- php驗(yàn)證身份證號(hào)碼正確性的函數(shù)
- php正則判斷是否為合法身份證號(hào)的方法
- PHP 身份證號(hào)驗(yàn)證函數(shù)
- php根據(jù)身份證號(hào)碼計(jì)算年齡的實(shí)例代碼
- php提取身份證號(hào)碼中的生日日期以及驗(yàn)證是否為成年人的函數(shù)
- 使用php從身份證號(hào)中獲取一系列線索(星座、生肖、生日等)
- PHP實(shí)現(xiàn)可精確驗(yàn)證身份證號(hào)碼的工具類(lèi)示例
- php身份證號(hào)碼檢查類(lèi)實(shí)例
- PHP用身份證號(hào)獲取星座和生肖的方法
- PHP校驗(yàn)15位和18位身份證號(hào)的類(lèi)封裝
- PHP實(shí)現(xiàn)15位身份證號(hào)轉(zhuǎn)18位的方法分析
相關(guān)文章
Laravel模型間關(guān)系設(shè)置分表的方法示例
這篇文章主要給大家介紹了關(guān)于Laravel模型間關(guān)系設(shè)置分表的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04
PHP SPL標(biāo)準(zhǔn)庫(kù)之?dāng)?shù)據(jù)結(jié)構(gòu)堆(SplHeap)簡(jiǎn)單使用實(shí)例
這篇文章主要介紹了PHP SPL標(biāo)準(zhǔn)庫(kù)之?dāng)?shù)據(jù)結(jié)構(gòu)堆(SplHeap)簡(jiǎn)單使用實(shí)例,本文還同時(shí)講解了最大堆(SplMaxHeap)、最小堆(SplMinHeap)的相關(guān)知識(shí),需要的朋友可以參考下2015-05-05
PHP頁(yè)面輸出時(shí)js設(shè)置input框的選中值
這篇文章主要介紹了PHP頁(yè)面輸出時(shí)js設(shè)置input框的選中值代碼,代碼簡(jiǎn)單易懂,需要的朋友可以參考下2016-09-09
php高清晰度無(wú)損圖片壓縮功能的實(shí)現(xiàn)代碼
經(jīng)常會(huì)用到把上傳的大圖片壓縮,特別是體積,在微信等APP應(yīng)用上,也默認(rèn)都是有壓縮的,那么,怎么樣對(duì)圖片大幅度壓縮卻仍能保持較高的清晰度呢?接下來(lái)通過(guò)本文給大家分享php高清晰度無(wú)損圖片壓縮功能,感興趣的朋友一起看看吧2018-12-12
PHP增刪改查項(xiàng)目的實(shí)戰(zhàn)詳解
這篇文章主要為大家詳細(xì)介紹了PHP增刪改查項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03
PHP下通過(guò)QRCode類(lèi)庫(kù)創(chuàng)建中間帶網(wǎng)站LOGO的二維碼
這篇文章主要介紹了用php中QRCode類(lèi)庫(kù)創(chuàng)建中間帶LOGO的二維碼,QRcode生成二維碼的實(shí)例代碼,有需要的朋友可以參考下2014-07-07
ThinkPHP中的關(guān)聯(lián)模型注意點(diǎn)
這篇文章主要介紹了初學(xué)ThinkPHP中的關(guān)聯(lián)模型注意點(diǎn),需要的朋友可以參考下2014-06-06
php學(xué)習(xí)Eloquent修改器源碼示例解析
這篇文章主要為大家介紹了php學(xué)習(xí)Eloquent修改器源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06

