Skip to content

Commit e08d4f8

Browse files
committed
Refactor
1 parent a375995 commit e08d4f8

File tree

4 files changed

+273
-263
lines changed

4 files changed

+273
-263
lines changed

src/Checker.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
namespace Jxlwqq\IdValidator;
4+
/**
5+
* Trait Checker
6+
*/
7+
trait Checker
8+
{
9+
10+
/**
11+
* 检查并拆分身份证号.
12+
*
13+
* @param string $id 身份证号
14+
*
15+
* @return array|bool
16+
*/
17+
private function _checkIdArgument($id)
18+
{
19+
$id = strtoupper($id);
20+
$length = strlen($id);
21+
$code = false;
22+
switch ($length) {
23+
case 18:
24+
$code = [
25+
'body' => substr($id, 0, 17),
26+
'addressCode' => substr($id, 0, 6),
27+
'birthdayCode' => substr($id, 6, 8),
28+
'order' => substr($id, 14, 3),
29+
'checkBit' => substr($id, -1),
30+
'type' => 18,
31+
];
32+
break;
33+
case 15:
34+
$code = [
35+
'body' => $id,
36+
'addressCode' => substr($id, 0, 6),
37+
'birthdayCode' => '19'.substr($id, 6, 6),
38+
'order' => substr($id, 12, 3),
39+
'checkBit' => '',
40+
'type' => 15,
41+
];
42+
break;
43+
}
44+
45+
return $code;
46+
}
47+
48+
/**
49+
* 检查地址码
50+
*
51+
* @param string $addressCode 地址码
52+
*
53+
* @return bool
54+
*/
55+
private function _checkAddressCode($addressCode)
56+
{
57+
$addressInfo = $this->_getAddressInfo($addressCode);
58+
59+
return $addressInfo ? true : false;
60+
}
61+
62+
/**
63+
* 检查顺序码
64+
*
65+
* @param string $orderCode 顺序码
66+
*
67+
* @return bool
68+
*/
69+
private function _checkOrderCode($orderCode)
70+
{
71+
if (strlen($orderCode) == 3) {
72+
return true;
73+
} else {
74+
return false;
75+
}
76+
}
77+
78+
/**
79+
* 检查出生日期码
80+
*
81+
* @param string $birthdayCode 出生日期码
82+
*
83+
* @return bool
84+
*/
85+
private function _checkBirthdayCode($birthdayCode)
86+
{
87+
$year = intval(substr($birthdayCode, 0, 4));
88+
$month = intval(substr($birthdayCode, 4, 2));
89+
$day = intval(substr($birthdayCode, -2));
90+
91+
if ($year < 1800) {
92+
return false;
93+
}
94+
if ($month > 12 || $month === 0 || $day > 31 || $day === 0) {
95+
return false;
96+
}
97+
98+
return true;
99+
}
100+
}

src/Generator.php

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
namespace Jxlwqq\IdValidator;
4+
5+
/**
6+
* Trait Generator
7+
*/
8+
trait Generator
9+
{
10+
/**
11+
* 生成顺序码
12+
*
13+
* @param int $sex 性别
14+
*
15+
* @return int|string
16+
*/
17+
private function _generatorOrderCode($sex)
18+
{
19+
$orderCode = $this->_getStrPad($this->_getRandInt(999, 1), 3, '1');
20+
if ($sex === 1) {
21+
$orderCode = $orderCode % 2 === 0 ? $orderCode - 1 : $orderCode;
22+
}
23+
if ($sex === 0) {
24+
$orderCode = $orderCode % 2 === 0 ? $orderCode : $orderCode - 1;
25+
}
26+
27+
return $orderCode;
28+
}
29+
30+
/**
31+
* 生成出生日期码
32+
*
33+
* @param int|string $birthday 出生日期
34+
*
35+
* @return string
36+
*/
37+
private function _generatorBirthdayCode($birthday)
38+
{
39+
if ($birthday && is_numeric($birthday)) {
40+
$year = $this->_getStrPad(substr($birthday, 0, 4), 4);
41+
$month = $this->_getStrPad(substr($birthday, 4, 2), 2);
42+
$day = $this->_getStrPad(substr($birthday, 6, 2), 2);
43+
}
44+
if (!isset($year) || empty($year) || $year < 1800 || $year > date('Y')) {
45+
$year = $this->_getStrPad($this->_getRandInt(99, 50), 2, '0');
46+
$year = '19'.$year;
47+
}
48+
49+
if (!isset($month) || empty($month) || $month < 1 || $month > 12) {
50+
$month = $this->_getStrPad($this->_getRandInt(12, 1), 2, '0');
51+
}
52+
53+
if (!isset($day) || empty($day) || $day < 1 || $day > 31) {
54+
$day = $this->_getStrPad($this->_getRandInt(28, 1), 2, '0');
55+
}
56+
57+
if (!checkdate($month, $day, $year)) {
58+
$year = $this->_getStrPad($this->_getRandInt(99, 50), 2, '0');
59+
$month = $this->_getStrPad($this->_getRandInt(12, 1), 2, '0');
60+
$day = $this->_getStrPad($this->_getRandInt(28, 1), 2, '0');
61+
}
62+
$birthdayCode = $year.$month.$day;
63+
64+
return $birthdayCode;
65+
}
66+
67+
/**
68+
* 生成地址码
69+
*
70+
* @param string $address 地址(行政区全称)
71+
* @return false|int|string
72+
*/
73+
private function _generatorAddressCode($address)
74+
{
75+
$addressCode = '';
76+
if ($address) {
77+
$addressCode = array_search($address, $this->_addressCodeList);
78+
}
79+
if ($addressCode && substr($addressCode, 0, 1) != 8) {
80+
// 台湾省、香港特别行政区和澳门特别行政区(8字开头)暂缺地市和区县信息
81+
// 省级
82+
if (substr($addressCode, 2, 4) == '0000') {
83+
$keys = array_keys($this->_addressCodeList);
84+
$provinceCode = substr($addressCode, 0, 2);
85+
$pattern = '/^'.$provinceCode.'\d{2}[^0]{2}$/';
86+
$result = preg_grep($pattern, $keys);
87+
$addressCode = $result[array_rand($result)];
88+
}
89+
// 市级
90+
if (substr($addressCode, 4, 2) == '00') {
91+
$keys = array_keys($this->_addressCodeList);
92+
$cityCode = substr($addressCode, 0, 4);
93+
$pattern = '/^'.$cityCode.'[^0]{2}$/';
94+
$result = preg_grep($pattern, $keys);
95+
$addressCode = $result[array_rand($result)];
96+
}
97+
} else {
98+
$addressCode = '110100'; // Default value
99+
for ($i = 0; $i < 100; $i++) {
100+
$province = $this->_getStrPad($this->_getRandInt(66), 2, '0');
101+
$city = $this->_getStrPad($this->_getRandInt(20), 2, '0');
102+
$district = $this->_getStrPad($this->_getRandInt(20), 2, '0');
103+
$fakeAddressCode = $province.$city.$district;
104+
if (isset($this->_addressCodeList[$fakeAddressCode])) {
105+
$addressCode = $fakeAddressCode;
106+
break;
107+
}
108+
}
109+
}
110+
111+
return $addressCode;
112+
}
113+
114+
/**
115+
* 生成校验码
116+
* 详细计算方法 @lint https://zh.wikipedia.org/wiki/中华人民共和国公民身份号码
117+
*
118+
* @param string $body 身份证号 body 部分
119+
*
120+
* @return int|string
121+
*/
122+
private function _generatorCheckBit($body)
123+
{
124+
// 位置加权
125+
$posWeight = [];
126+
for ($i = 18; $i > 1; $i--) {
127+
$weight = pow(2, $i - 1) % 11;
128+
$posWeight[$i] = $weight;
129+
};
130+
131+
// 累身份证号 body 部分与位置加权的积
132+
$bodySum = 0;
133+
$bodyArray = str_split($body);
134+
$count = count($bodyArray);
135+
for ($j = 0; $j < $count; $j++) {
136+
$bodySum += (intval($bodyArray[$j], 10) * $posWeight[18 - $j]);
137+
}
138+
139+
// 生成校验码
140+
$checkBit = 12 - ($bodySum % 11);
141+
if ($checkBit == 10) {
142+
$checkBit = 'X';
143+
} elseif ($checkBit > 10) {
144+
$checkBit = $checkBit % 11;
145+
}
146+
147+
return $checkBit;
148+
}
149+
}

0 commit comments

Comments
 (0)