forked from jxlwqq/id-validator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHelper.php
More file actions
318 lines (286 loc) · 8.58 KB
/
Helper.php
File metadata and controls
318 lines (286 loc) · 8.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<?php
namespace Jxlwqq\IdValidator;
/**
* Trait Helper.
*/
trait Helper
{
/**
* 获取位置加权.
*
* @return array
*/
private function _getPosWeight()
{
$posWeight = [];
for ($i = 18; $i > 1; $i--) {
$weight = pow(2, $i - 1) % 11;
$posWeight[$i] = $weight;
}
return $posWeight;
}
/**
* 获取数字补位.
*
* @param $str
* @param int $len 长度
* @param string $chr 补位值
* @param bool $right 左右
*
* @return string
*/
private function _getStrPad($str, $len = 2, $chr = '0', $right = false)
{
$str = strval($str);
if (strlen($str) >= $len) {
return $str;
} else {
for ($i = 0, $j = $len - strlen($str); $i < $j; $i++) {
if ($right) {
$str = $str.$chr;
} else {
$str = $chr.$str;
}
}
return $str;
}
}
/**
* 获取地址码信息.
*
* @param string $addressCode 地址码
*
* @return bool|mixed|string
*/
private function _getAddressInfo($addressCode)
{
$addressInfo = [];
$firstCharacter = substr($addressCode, 0, 1); // 用于判断是否是港澳台居民居住证(8字开头)
// 省级信息
$provinceAddressCode = substr($addressCode, 0, 2).'0000';
$addressInfo['province'] = isset($this->_addressCodeList[$provinceAddressCode]) ? $this->_addressCodeList[$provinceAddressCode] : '';
// 市级信息(港澳台居民居住证无市级信息)
if ($firstCharacter != '8') {
$cityAddressCode = substr($addressCode, 0, 4).'00';
$addressInfo['city'] = isset($this->_addressCodeList[$cityAddressCode]) ? $this->_addressCodeList[$cityAddressCode] : '';
} else {
$addressInfo['city'] = '';
}
// 县级信息(港澳台居民居住证无县级信息)
if ($firstCharacter != '8') {
$addressInfo['district'] = isset($this->_addressCodeList[$addressCode]) ? $this->_addressCodeList[$addressCode] : '';
} else {
$addressInfo['district'] = '';
}
if (empty($addressInfo)) {
return false;
} else {
return $addressInfo;
}
}
/**
* 获取星座信息.
*
* @param string $birthdayCode 出生日期码
*
* @return string
*/
private function _getConstellation($birthdayCode)
{
$time = strtotime($birthdayCode);
$year = substr($birthdayCode, 0, 4);
$month = substr($birthdayCode, 4, 2);
$day = substr($birthdayCode, 6, 2);
// 1月份与12月份特殊处理
if (($month == 1 && $day < 20) || ($month == 12 && $day > 21)) {
return $this->_constellationList['12']['name'];
} elseif ($month == 1) {
return $this->_constellationList['01']['name'];
} elseif ($month == 12) {
return $this->_constellationList['12']['name'];
}
$startDate = $year.'-'.$this->_constellationList[$month]['start_date'];
$endDate = $year.'-'.$this->_constellationList[$month]['end_date'];
if (strtotime($startDate) <= $time && strtotime($endDate) >= $time) {
return $this->_constellationList[$month]['name'];
}
$startDate = $year.'-'.$this->_constellationList[$month - 1]['start_date'];
$endDate = $year.'-'.$this->_constellationList[$month - 1]['end_date'];
if (strtotime($startDate) <= $time && strtotime($endDate) >= $time) {
return $this->_constellationList[$month - 1]['name'];
}
return '';
}
/**
* 获取生肖信息.
*
* @param string $birthdayCode 出生日期码
*
* @return mixed
*/
private function _getChineseZodiac($birthdayCode)
{
$start = 1900; // 子鼠
$end = substr($birthdayCode, 0, 4);
$key = ($end - $start) % 12;
$key = $key >= 0 ? $key : ($key + 12);
return $this->_chineseZodiacList[$key];
}
/**
* 检查并拆分身份证号.
*
* @param string $id 身份证号
*
* @return array|bool
*/
private function _checkIdArgument($id)
{
$id = strtoupper($id);
$length = strlen($id);
$code = false;
switch ($length) {
case 18:
$code = [
'body' => substr($id, 0, 17),
'addressCode' => substr($id, 0, 6),
'birthdayCode' => substr($id, 6, 8),
'order' => substr($id, 14, 3),
'checkBit' => substr($id, -1),
'type' => 18,
];
break;
case 15:
$code = [
'body' => $id,
'addressCode' => substr($id, 0, 6),
'birthdayCode' => '19'.substr($id, 6, 6),
'order' => substr($id, 12, 3),
'checkBit' => '',
'type' => 15,
];
break;
}
return $code;
}
/**
* 检查地址码
*
* @param string $addressCode 地址码
*
* @return bool
*/
private function _checkAddressCode($addressCode)
{
$addressInfo = $this->_getAddressInfo($addressCode);
return $addressInfo ? true : false;
}
/**
* 检查出生日期码
*
* @param string $birthdayCode 出生日期码
*
* @return bool
*/
private function _checkBirthdayCode($birthdayCode)
{
$year = intval(substr($birthdayCode, 0, 4));
$month = intval(substr($birthdayCode, 4, 2));
$day = intval(substr($birthdayCode, -2));
if ($year < 1800) {
return false;
}
if ($month > 12 || $month === 0 || $day > 31 || $day === 0) {
return false;
}
return true;
}
/**
* 检查顺序码
*
* @param string $orderCode 顺序码
*
* @return bool
*/
private function _checkOrderCode($orderCode)
{
if (strlen($orderCode) == 3) {
return true;
} else {
return false;
}
}
/**
* 生成随机数.
*
* @param int $max 最大值
* @param int $min 最小值
*
* @return int
*/
private function _generatorRandInt($max, $min = 1)
{
return rand($min, $max);
}
/**
* 生成校验码
* 详细计算方法 @lint https://zh.wikipedia.org/wiki/中华人民共和国公民身份号码
*
* @param string $body 身份证号 body 部分
*
* @return int|string
*/
private function _generatorCheckBit($body)
{
// 位置加权
$posWeight = $this->_getPosWeight();
// 累身份证号 body 部分与位置加权的积
$bodySum = 0;
$bodyArray = str_split($body);
$count = count($bodyArray);
for ($j = 0; $j < $count; $j++) {
$bodySum += (intval($bodyArray[$j], 10) * $posWeight[18 - $j]);
}
// 生成校验码
$checkBit = 12 - ($bodySum % 11);
if ($checkBit == 10) {
$checkBit = 'X';
} elseif ($checkBit > 10) {
$checkBit = $checkBit % 11;
}
return $checkBit;
}
/**
* 生成地址码
*
* @return string
*/
private function _generatorAddressCode()
{
$addressCode = '110100';
for ($i = 0; $i < 100; $i++) {
$province = $this->_getStrPad($this->_generatorRandInt(66), 2, '0');
$city = $this->_getStrPad($this->_generatorRandInt(20), 2, '0');
$district = $this->_getStrPad($this->_generatorRandInt(20), 2, '0');
$fakeAddressCode = $province.$city.$district;
if (isset($this->_addressCodeList[$fakeAddressCode])) {
$addressCode = $fakeAddressCode;
break;
}
}
return $addressCode;
}
/**
* 生成出生日期码
*
* @return string
*/
private function _generatorBirthdayCode()
{
$year = $this->_getStrPad($this->_generatorRandInt(99, 50), 2, '0');
$month = $this->_getStrPad($this->_generatorRandInt(12, 1), 2, '0');
$day = $this->_getStrPad($this->_generatorRandInt(28, 1), 2, '0');
$year = '19'.$year;
$birthdayCode = $year.$month.$day;
return $birthdayCode;
}
}