Skip to content

Commit

Permalink
Merge pull request #2 from ofcold/master
Browse files Browse the repository at this point in the history
Master
  • Loading branch information
lilianjin authored May 25, 2018
2 parents bbaade9 + 94e6d8b commit 55c1cac
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 118 deletions.
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,16 @@
#### 验证你的身份证号码
```php

try {
Ofcold\IdentityCard\IdentityCard::make('32010619831029081');
// 返回false 或 Ofcold\IdentityCard\IdentityCard
$result = Ofcold\IdentityCard\IdentityCard::make('32010619831029081');

return true;
}
catch (\Exception $e)
{
print_r($e->getMessage());
return false;
if ( $result !== false ) {

return '您的身份证号码不正确';
}

print_r($result->toArray());

```

#### 或运行测试文件
Expand All @@ -56,9 +55,9 @@
```php

try {
$idCard = Ofcold\IdentityCard\IdentityCard::make('320106198310290811');
$idCard = Ofcold\IdentityCard\IdentityCard::make('142701198003124054');
// Use locale, Current supported zh-cn,en
// $idCard = Ofcold\IdentityCard\IdentityCard::make('320106198310290811', 'zh-cn');
// $idCard = Ofcold\IdentityCard\IdentityCard::make('142701198003124054', 'zh-cn');
$area = $idCard->getArea();
$gender = $idCard->getGender();
$birthday = $idCard->getBirthday();
Expand All @@ -77,13 +76,18 @@
#### 返回结果:
```json

{
"area": "Jiang 南京市 鼓楼区",
"gender": "male",
"birthday": "1983-10-29",
"age": 34,
"constellation": "天蝎座"
}
Array
(
[area] => 山西省 运城地区 运城市
[province] => 山西省
[city] => 运城地区
[county] => 运城市
[gender] => 男
[birthday] => 1980-03-12
[age] => 38
[constellation] => 双鱼座
)

```


Expand Down
33 changes: 19 additions & 14 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ A component based on People's Republic of China citizen ID card to obtain the us
#### Verify your Chinese ID card
```php

try {
$idCard = Ofcold\IdentityCard\IdentityCard::make('32010619831029081');
print_r($idCard->toArray());
}
catch (\Exception $e)
{
print_r($e->getMessage());
// Result false OR Ofcold\IdentityCard\IdentityCard instance.
$result = Ofcold\IdentityCard\IdentityCard::make('32010619831029081');

if ( $result !== false ) {

return 'Your ID number is incorrect';
}

print_r($result->toArray());


```

Expand Down Expand Up @@ -65,13 +66,17 @@ A component based on People's Republic of China citizen ID card to obtain the us
#### Results:
```json

{
"area": "Jiangsu Nanjing Gulouqu",
"gender": "male",
"birthday": "1983-10-29",
"age": 34,
"constellation": "Scorpio"
}
Array
(
[area] => shan xi sheng yun cheng di qu yun cheng shi
[province] => shan xi sheng
[city] => yun cheng di qu
[county] => yun cheng shi
[gender] => Male
[birthday] => 1980-03-12
[age] => 38
[constellation] => Pisces
)
```

### Api
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
{
"name": "Olivia Fu",
"email": "olivia.fu@ofcold.com",
"email": "olivia@ofcold.com",
"homepage": "https://olivia.ink"
},
{
Expand All @@ -35,6 +35,10 @@
"Ofcold\\IdentityCard\\": "src/"
}
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.1"
},
"config": {
"sort-packages": true
},
Expand Down
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="IdentityCard Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
170 changes: 91 additions & 79 deletions src/IdentityCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

namespace Ofcold\IdentityCard;


/**
* Class IdentityCard
* Class IdentityCard
*
* @link https://ofcold.com
* @link https://ofcold.com/license
*
* @link https://ofcold.ink
* @author Ofcold <support@ofcold.com>
* @author Olivia Fu <olivia@ofcold.com>
* @author Bill Li <bill.li@ofcold.com>
*
* @author Ofcold, Inc <support@ofcold.com>
* @author Olivia Fu <olivia@ofcold.com>
* @author Bill Li <bill.li@ofcold.com>
* @package Ofcold\IdentityCard\IdentityCard
*
* @package Ofcold\IdentityCard\IdentityCard
* @copyright Copyright (c) 2017-2018, Ofcold. All rights reserved.
*/
class IdentityCard
{
Expand Down Expand Up @@ -51,6 +53,11 @@ public static function make(string $idCard, string $locale = 'zh-cn')

static::$locale = in_array($locale, ['zh-cn', 'en']) ? $locale : 'zh-cn';

if ( static::check() === false )
{
return false;
}

return static::$instance ?: static::$instance = new static;
}

Expand All @@ -64,6 +71,66 @@ public static function getLocale() : string
return static::$locale ?: 'zh-cn';
}

/**
* Verify your ID card is legal.
*
* @return bool
*/
protected static function check() : bool
{
$id = strtoupper(static::$idCard);

if ( static::checkFirst($id) === true )
{
$iYear = substr($id, 6, 4);
$iMonth = substr($id, 10, 2);
$iDay = substr($id, 12, 2);
if ( checkdate($iMonth, $iDay, $iYear) )
{
return static::getIDCardVerifyNumber(substr($id, 0, 17)) != substr($id, 17, 1) ? false : true;
}
}

return false;
}

/**
* Through the regular expression preliminary detection ID number illegality.
*
* @param string $idCard
*
* @return bool
*/
protected static function checkFirst(string $idCard) : bool
{
return preg_match('/^\d{6}(18|19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/', $idCard);
}

/**
* According to the first 17 digits of ID card to calculate the last check digit of ID card
*
* @param string $idcardBase
*
* @return string
*/
protected static function getIDCardVerifyNumber(string $idcardBase) : string
{
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];

$verifyNumberList = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

$checksum = 0;

for ( $i = 0; $i < strlen($idcardBase); $i++ )
{
$checksum += substr($idcardBase, $i, 1) * $factor[$i];
}

$mod = $checksum % 11;

return $verifyNumberList[$mod];
}

/**
* Constellations(Data from Wikipedia https://zh.wikipedia.org/wiki/%E8%A5%BF%E6%B4%8B%E5%8D%A0%E6%98%9F%E8%A1%93)
*
Expand Down Expand Up @@ -24752,75 +24819,6 @@ public static function getLocale() : string
*/
protected function __construct()
{
if ( ! $this->isCorrect() )
{
throw new \InvalidArgumentException([
'en' => 'Please provide the correct citizen ID number issued by the Chinese mainland government.',
'zh-cn' => '请提供中国大陆政府颁发的正确公民身份证号码。'
][static::getLocale()]);
}
}

/**
* Through the regular expression preliminary detection ID number illegality.
*
* @param string $idCard
*
* @return bool
*/
private function checkFirst(string $idCard) : bool
{
return preg_match('/^\d{6}(18|19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/', $idCard);
}

/**
* According to the first 17 digits of ID card to calculate the last check digit of ID card
*
* @param string $idcardBase
*
* @return string
*/
private function getIDCardVerifyNumber(string $idcardBase) : string
{
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];

$verifyNumberList = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$checksum = 0;
for ( $i = 0; $i < strlen($idcardBase); $i++ )
{
$checksum += substr($idcardBase, $i, 1) * $factor[$i];
}

$mod = $checksum % 11;

return $verifyNumberList[$mod];
}

/**
* Verify your ID card is legal.
*
* @return bool
*/
public function isCorrect() : bool
{
$id = strtoupper(static::$idCard);

if ( $this->checkFirst($id) === true )
{
$iYear = substr($id, 6, 4);
$iMonth = substr($id, 10, 2);
$iDay = substr($id, 12, 2);
if ( checkdate($iMonth, $iDay, $iYear) )
{
$idcardBase = substr($id, 0, 17);

return $this->getIDCardVerifyNumber($idcardBase) != substr($id, 17, 1) ? false : true;
}

}

return false;

}

/**
Expand Down Expand Up @@ -24927,9 +24925,9 @@ public function getBirthday(string $format = 'Y-m-d') : string
*/
public function getAge() : int
{
$birthday = strtotime(substr(static::$idCard, 6, 8));
$today = strtotime('today');
$diff = floor(($today - $birthday)/86400/365);

$diff = floor(($today - strtotime(substr(static::$idCard, 6, 8)))/86400/365);

return (int) strtotime(substr(static::$idCard,6,8).' +'.$diff.'years') > $today ? ($diff + 1) : $diff;
}
Expand All @@ -24942,7 +24940,7 @@ public function getAge() : int
public function getZodiac() : string
{
$locale = [
'zh-cn' => ['', '', '', '', '', '', '', '', '', '', '', '']
'zh-cn' => ['', '', '', '', '', '', '', '', '', '', '', ''],
'en' => ['Cow', 'Tiger', 'Rabbit', 'Dragon', 'Snake', 'Horse', 'Sheep', 'Monkey', 'Chicken', 'Dog', 'Pig', 'Rat']
][static::getLocale()];

Expand All @@ -24957,7 +24955,9 @@ public function getZodiac() : string
public function getConstellation() : string
{
$month = (int) substr(static::$idCard, 10, 2);

$month = $month - 1;

$day = (int) substr(static::$idCard, 12, 2);

if ( $day < $this->constellationEdgeDays[$month] )
Expand Down Expand Up @@ -25004,4 +25004,16 @@ public function toArray() : array
];
}

public function __get($key)
{
$result = $this->toArray();

return $result[$key] ?? $result;
}

public function __toString()
{
return $this->toJson();
}

}
Loading

0 comments on commit 55c1cac

Please sign in to comment.