Skip to content

Commit d2369a8

Browse files
committed
fakeId()增加可选参数:地址、出生日期和性别
1 parent 3b6ef87 commit d2369a8

File tree

3 files changed

+98
-28
lines changed

3 files changed

+98
-28
lines changed

src/Helper.php

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,19 @@ private function _getAddressInfo($addressCode)
6464
$firstCharacter = substr($addressCode, 0, 1); // 用于判断是否是港澳台居民居住证(8字开头)
6565
// 省级信息
6666
$provinceAddressCode = substr($addressCode, 0, 2).'0000';
67-
$addressInfo['province'] = isset($this->_addressCodeList[$provinceAddressCode]) ? $this->_addressCodeList[$provinceAddressCode] : '';
67+
$addressInfo['province'] = isset($this->_addressCodeList[$provinceAddressCode]) ? $this->_addressCodeList[$provinceAddressCode] : (isset($this->_abandonedAddressCodeList[$provinceAddressCode]) ? $this->_abandonedAddressCodeList[$provinceAddressCode] : '');
6868

6969
// 市级信息(港澳台居民居住证无市级信息)
7070
if ($firstCharacter != '8') {
7171
$cityAddressCode = substr($addressCode, 0, 4).'00';
72-
$addressInfo['city'] = isset($this->_addressCodeList[$cityAddressCode]) ? $this->_addressCodeList[$cityAddressCode] : '';
72+
$addressInfo['city'] = isset($this->_addressCodeList[$cityAddressCode]) ? $this->_addressCodeList[$cityAddressCode] : (isset($this->_abandonedAddressCodeList[$cityAddressCode]) ? $this->_abandonedAddressCodeList[$cityAddressCode] : '');
7373
} else {
7474
$addressInfo['city'] = '';
7575
}
7676

7777
// 县级信息(港澳台居民居住证无县级信息)
7878
if ($firstCharacter != '8') {
79-
$addressInfo['district'] = isset($this->_addressCodeList[$addressCode]) ? $this->_addressCodeList[$addressCode] : '';
79+
$addressInfo['district'] = isset($this->_addressCodeList[$addressCode]) ? $this->_addressCodeList[$addressCode] : (isset($this->_abandonedAddressCodeList[$addressCode]) ? $this->_abandonedAddressCodeList[$addressCode] : '');
8080
} else {
8181
$addressInfo['district'] = '';
8282
}
@@ -287,17 +287,41 @@ private function _generatorCheckBit($body)
287287
*
288288
* @return string
289289
*/
290-
private function _generatorAddressCode()
290+
private function _generatorAddressCode($address)
291291
{
292-
$addressCode = '110100';
293-
for ($i = 0; $i < 100; $i++) {
294-
$province = $this->_getStrPad($this->_generatorRandInt(66), 2, '0');
295-
$city = $this->_getStrPad($this->_generatorRandInt(20), 2, '0');
296-
$district = $this->_getStrPad($this->_generatorRandInt(20), 2, '0');
297-
$fakeAddressCode = $province.$city.$district;
298-
if (isset($this->_addressCodeList[$fakeAddressCode])) {
299-
$addressCode = $fakeAddressCode;
300-
break;
292+
$addressCode = '';
293+
if ($address) {
294+
$addressCode = array_search($address, $this->_addressCodeList);
295+
}
296+
if ($addressCode && substr($addressCode, 0, 1) != 8) {
297+
// 台湾省、香港特别行政区和澳门特别行政区(8字开头)暂缺地市和区县信息
298+
// 省级
299+
if (substr($addressCode, 2, 4) == '0000') {
300+
$keys = array_keys($this->_addressCodeList);
301+
$provinceCode = substr($addressCode, 0, 2);
302+
$pattern = '/^'.$provinceCode.'\d{2}[^0]{2}$/';
303+
$result = preg_grep($pattern, $keys);
304+
$addressCode = $result[array_rand($result)];
305+
}
306+
// 市级
307+
if (substr($addressCode, 4, 2) == '00') {
308+
$keys = array_keys($this->_addressCodeList);
309+
$cityCode = substr($addressCode, 0, 4);
310+
$pattern = '/^'.$cityCode.'[^0]{2}$/';
311+
$result = preg_grep($pattern, $keys);
312+
$addressCode = $result[array_rand($result)];
313+
}
314+
} else {
315+
$addressCode = '110100'; // Default value
316+
for ($i = 0; $i < 100; $i++) {
317+
$province = $this->_getStrPad($this->_generatorRandInt(66), 2, '0');
318+
$city = $this->_getStrPad($this->_generatorRandInt(20), 2, '0');
319+
$district = $this->_getStrPad($this->_generatorRandInt(20), 2, '0');
320+
$fakeAddressCode = $province.$city.$district;
321+
if (isset($this->_addressCodeList[$fakeAddressCode])) {
322+
$addressCode = $fakeAddressCode;
323+
break;
324+
}
301325
}
302326
}
303327

@@ -309,14 +333,51 @@ private function _generatorAddressCode()
309333
*
310334
* @return string
311335
*/
312-
private function _generatorBirthdayCode()
336+
private function _generatorBirthdayCode($birthday)
313337
{
314-
$year = $this->_getStrPad($this->_generatorRandInt(99, 50), 2, '0');
315-
$month = $this->_getStrPad($this->_generatorRandInt(12, 1), 2, '0');
316-
$day = $this->_getStrPad($this->_generatorRandInt(28, 1), 2, '0');
317-
$year = '19'.$year;
338+
if ($birthday && is_numeric($birthday)) {
339+
$year = $this->_getStrPad(substr($birthday, 0,4), 4);
340+
$month = $this->_getStrPad(substr($birthday, 4, 2), 2);
341+
$day = $this->_getStrPad(substr($birthday, 6, 2), 2);
342+
343+
}
344+
if (!isset($year) || empty($year) || $year < 1800 || $year > date('Y')) {
345+
$year = $this->_getStrPad($this->_generatorRandInt(99, 50), 2, '0');
346+
$year = '19'.$year;
347+
}
348+
349+
if (!isset($month) || empty($month) || $month < 1 || $month > 12) {
350+
$month = $this->_getStrPad($this->_generatorRandInt(12, 1), 2, '0');
351+
}
352+
353+
if (!isset($day) || empty($day) || $day < 1 || $day > 31) {
354+
$day = $this->_getStrPad($this->_generatorRandInt(28, 1), 2, '0');
355+
}
356+
357+
if (!checkdate($month, $day, $year)) {
358+
$year = $this->_getStrPad($this->_generatorRandInt(99, 50), 2, '0');
359+
$month = $this->_getStrPad($this->_generatorRandInt(12, 1), 2, '0');
360+
$day = $this->_getStrPad($this->_generatorRandInt(28, 1), 2, '0');
361+
}
318362
$birthdayCode = $year.$month.$day;
319363

320364
return $birthdayCode;
321365
}
366+
367+
/**
368+
* 生成顺序码
369+
*
370+
* @return string
371+
*/
372+
private function _generatorOrderCode($sex)
373+
{
374+
$orderCode = $this->_getStrPad($this->_generatorRandInt(999, 1), 3, '1');
375+
if ($sex === 1) {
376+
$orderCode = $orderCode % 2 === 0 ? $orderCode -1 : $orderCode;
377+
}
378+
if ($sex === 0) {
379+
$orderCode = $orderCode % 2 === 0 ? $orderCode : $orderCode -1;
380+
}
381+
return $orderCode;
382+
}
322383
}

src/IdValidator.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class IdValidator
99
{
1010
use Helper;
1111

12-
private $_addressCodeList = []; // 所有地址码数据(现行+废弃)
12+
private $_addressCodeList = []; // 现行地址码数据
1313
private $_abandonedAddressCodeList = []; // 废弃地址码数据
1414
private $_constellationList = [];
1515
private $_chineseZodiacList = [];
@@ -19,10 +19,8 @@ class IdValidator
1919
*/
2020
public function __construct()
2121
{
22-
$addressCodeList = include __DIR__.'/../data/addressCode.php';
23-
$abandonedAddressCodeList = include __DIR__.'/../data/abandonedAddressCode.php';
24-
$this->_abandonedAddressCodeList = $abandonedAddressCodeList;
25-
$this->_addressCodeList = $addressCodeList + $abandonedAddressCodeList;
22+
$this->_addressCodeList = include __DIR__.'/../data/addressCode.php';
23+
$this->_abandonedAddressCodeList = include __DIR__.'/../data/abandonedAddressCode.php';
2624
$this->_constellationList = include __DIR__.'/../data/constellation.php';
2725
$this->_chineseZodiacList = include __DIR__.'/../data/chineseZodiac.php';
2826
}
@@ -103,29 +101,35 @@ public function getInfo($id)
103101
}
104102

105103
/**
106-
* 生成假数据.
104+
* * 生成假数据.
107105
*
108106
* @param bool $eighteen 是否为 18 位
107+
* @param null|string|array $address 地址
108+
* @param null|string|int $sex 性别(1为男性,0位女性)
109+
* @param null|string|int|array $birthday 出生日期
109110
*
110111
* @return string
111112
*/
112-
public function fakeId($eighteen = true)
113+
public function fakeId($eighteen = true, $address = null, $birthday = null, $sex = null)
113114
{
114115
// 生成地址码
115-
$addressCode = $this->_generatorAddressCode();
116+
$addressCode = $this->_generatorAddressCode($address);
116117

117118
// 出生日期码
118-
$birthdayCode = $this->_generatorBirthdayCode();
119+
$birthdayCode = $this->_generatorBirthdayCode($birthday);
119120

120121
if (!$eighteen) {
121122
return $addressCode.substr($birthdayCode, 2)
122123
.$this->_getStrPad($this->_generatorRandInt(999, 1), 3, '1');
123124
}
124125

125-
$body = $addressCode.$birthdayCode.$this->_getStrPad($this->_generatorRandInt(999, 1), 3, '1');
126+
$orderCode = $this->_generatorOrderCode($sex);
127+
128+
$body = $addressCode.$birthdayCode.$orderCode;
126129

127130
$checkBit = $this->_generatorCheckBit($body);
128131

129132
return $body.$checkBit;
130133
}
134+
131135
}

tests/IdValidatorTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public function testFakeId()
2424
$idValidator = new IdValidator();
2525
$this->assertEquals(true, $idValidator->isValid($idValidator->fakeId()));
2626
$this->assertEquals(true, $idValidator->isValid($idValidator->fakeId(false)));
27+
$this->assertEquals(true, $idValidator->isValid($idValidator->fakeId(true, '上海市', '2000', 1)));
28+
$this->assertEquals(true, $idValidator->isValid($idValidator->fakeId(true, '江苏省', '20000101', 1)));
29+
$this->assertEquals(true, $idValidator->isValid($idValidator->fakeId(true, '台湾省', '20131010', 0)));
30+
31+
2732
}
2833

2934
public function testGetInfo()

0 commit comments

Comments
 (0)