forked from jxlwqq/id-validator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGenerator.php
More file actions
155 lines (139 loc) · 4.79 KB
/
Generator.php
File metadata and controls
155 lines (139 loc) · 4.79 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
<?php
namespace Jxlwqq\IdValidator;
/**
* Trait Generator.
*/
trait Generator
{
/**
* 生成顺序码
*
* @param int $sex 性别
*
* @return int|string
*/
private function _generatorOrderCode($sex)
{
$orderCode = $this->_getStrPad($this->_getRandInt(999, 1), 3, '1');
if ($sex === 1) {
$orderCode = $orderCode % 2 === 0 ? $orderCode - 1 : $orderCode;
}
if ($sex === 0) {
$orderCode = $orderCode % 2 === 0 ? $orderCode : $orderCode - 1;
}
return $orderCode;
}
/**
* 生成出生日期码
*
* @param int|string $birthday 出生日期
*
* @return string
*/
private function _generatorBirthdayCode($birthday)
{
if ($birthday && is_numeric($birthday)) {
$year = $this->_getStrPad(substr($birthday, 0, 4), 4);
$month = $this->_getStrPad(substr($birthday, 4, 2), 2);
$day = $this->_getStrPad(substr($birthday, 6, 2), 2);
}
if (!isset($year) || empty($year) || $year < 1800 || $year > date('Y')) {
$year = $this->_getStrPad($this->_getRandInt(99, 50), 2, '0');
$year = '19'.$year;
}
if (!isset($month) || empty($month) || $month < 1 || $month > 12) {
$month = $this->_getStrPad($this->_getRandInt(12, 1), 2, '0');
}
if (!isset($day) || empty($day) || $day < 1 || $day > 31) {
$day = $this->_getStrPad($this->_getRandInt(28, 1), 2, '0');
}
if (!checkdate($month, $day, $year)) {
$year = $this->_getStrPad($this->_getRandInt(99, 50), 2, '0');
$month = $this->_getStrPad($this->_getRandInt(12, 1), 2, '0');
$day = $this->_getStrPad($this->_getRandInt(28, 1), 2, '0');
}
$birthdayCode = $year.$month.$day;
return $birthdayCode;
}
/**
* 生成地址码
*
* @param string $address 地址(行政区全称)
*
* @return false|int|string
*/
private function _generatorAddressCode($address)
{
$addressCode = '';
if ($address) {
$addressCode = array_search($address, $this->_addressCodeList);
}
if ($addressCode && substr($addressCode, 0, 1) == 8) {
// 台湾省、香港特别行政区和澳门特别行政区(8字开头)暂缺地市和区县信息
return $addressCode;
}
if ($addressCode) {
// 省级
if (substr($addressCode, 2, 4) == '0000') {
$keys = array_keys($this->_addressCodeList);
$provinceCode = substr($addressCode, 0, 2);
$pattern = '/^'.$provinceCode.'\d{2}[^0]{2}$/';
$result = preg_grep($pattern, $keys);
$addressCode = $result[array_rand($result)];
}
// 市级
if (substr($addressCode, 4, 2) == '00') {
$keys = array_keys($this->_addressCodeList);
$cityCode = substr($addressCode, 0, 4);
$pattern = '/^'.$cityCode.'[^0]{2}$/';
$result = preg_grep($pattern, $keys);
$addressCode = $result[array_rand($result)];
}
} else {
$addressCode = '110100'; // Default value
for ($i = 0; $i < 100; $i++) {
$province = $this->_getStrPad($this->_getRandInt(66), 2, '0');
$city = $this->_getStrPad($this->_getRandInt(20), 2, '0');
$district = $this->_getStrPad($this->_getRandInt(20), 2, '0');
$fakeAddressCode = $province.$city.$district;
if (isset($this->_addressCodeList[$fakeAddressCode])) {
$addressCode = $fakeAddressCode;
break;
}
}
}
return $addressCode;
}
/**
* 生成校验码
* 详细计算方法 @lint https://zh.wikipedia.org/wiki/中华人民共和国公民身份号码
*
* @param string $body 身份证号 body 部分
*
* @return int|string
*/
private function _generatorCheckBit($body)
{
// 位置加权
$posWeight = [];
for ($i = 18; $i > 1; $i--) {
$weight = pow(2, $i - 1) % 11;
$posWeight[$i] = $weight;
}
// 累身份证号 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;
}
}