Skip to content

Commit

Permalink
Add Valid National Code Generator to fa_IR
Browse files Browse the repository at this point in the history
  • Loading branch information
thearsalan committed Apr 1, 2019
1 parent 76b1c25 commit cb01380
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
9 changes: 9 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,15 @@ echo $faker->vat; // "A35864370"
echo $faker->dni; // '83367512'
```

### `Faker\Provider\fa_IR\Person`

```php
<?php

// Generates a valid nationalCode
echo $faker->nationalCode; // "0078475759"
```

### `Faker\Provider\fa_IR\Address`

```php
Expand Down
64 changes: 64 additions & 0 deletions src/Faker/Provider/fa_IR/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,68 @@ class Person extends \Faker\Provider\Person

protected static $titleMale = array('آقای', 'استاد', 'دکتر', 'مهندس');
protected static $titleFemale = array('خانم', 'استاد', 'دکتر', 'مهندس');

/**
* This method returns a valid Iranian nationalCode
* @example '8075859741'
* @link https://fa.wikipedia.org/wiki/%DA%A9%D8%A7%D8%B1%D8%AA_%D8%B4%D9%86%D8%A7%D8%B3%D8%A7%DB%8C%DB%8C_%D9%85%D9%84%DB%8C#%D8%AD%D8%B3%D8%A7%D8%A8_%DA%A9%D8%B1%D8%AF%D9%86_%DA%A9%D8%AF_%DA%A9%D9%86%D8%AA%D8%B1%D9%84
* @return string
*/
public static function nationalCode()
{
$area = self::createAreaCode();
$core = self::createCoreCode();
$control = self::createControlCode($area, $core);

return sprintf("%03d%06d%01d", $area, $core, $control);
}

/**
* This method generates a 3-digit valid area code to be used in nationalCode
* @return int|string
*/
private static function createAreaCode()
{
$area = "000";

while ($area == "000") {
$area = static::numerify("###");
}

return $area;
}

/**
* This method randomly generates a 6-digit core code for nationalCode
* @return string
*/
private static function createCoreCode()
{
return static::numerify("######");
}

/**
* This method uses the Iranian nationalCode validation algorithm to generate a valid 10-digit code
* @param $area
* @param $core
* @link https://fa.wikipedia.org/wiki/%DA%A9%D8%A7%D8%B1%D8%AA_%D8%B4%D9%86%D8%A7%D8%B3%D8%A7%DB%8C%DB%8C_%D9%85%D9%84%DB%8C#%D8%AD%D8%B3%D8%A7%D8%A8_%DA%A9%D8%B1%D8%AF%D9%86_%DA%A9%D8%AF_%DA%A9%D9%86%D8%AA%D8%B1%D9%84
* @return int
*/
private static function createControlCode($area, $core)
{
$subNationalCodeString = $area . $core;

$sum = 0;
$count = 0;

for ($i = 10; $i > 1; $i--) {
$sum += $subNationalCodeString[$count] * ($i);
$count++;
}

if (($sum % 11) < 2) {
return $sum % 11;
}
return 11 - ($sum % 11);
}
}
54 changes: 54 additions & 0 deletions test/Faker/Provider/fa_IR/PersonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Faker\Test\Provider\fa_IR;

use Faker\Provider\fa_IR\Person;
use Faker\Generator;
use PHPUnit\Framework\TestCase;

class PersonTest extends TestCase
{

/**
* @var Generator
*/
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testNationalCode()
{
for ($i = 0; $i < 100; $i++) {
$nationalCode = $this->faker->nationalCode;

// nationalCode should be in the format ##########
$this->assertRegExp('/^[0-9]{10}$/', $nationalCode);

$areaCode = substr($nationalCode, 0, 3);
$controlCode = substr($nationalCode, 9, 1);

// the areaCode must in the format ###, excluding '000'
$this->assertNotEquals('000', $areaCode);

// the controlCode should comply with the Iranian National Code validation algorithm
$sum = 0;
$count = 0;

for ($j = 10; $j > 1; $j--) {
$sum += $nationalCode[$count] * ($j);
$count++;
}

if (($sum % 11) < 2) {
$this->assertEquals($sum % 11, (int)$controlCode);
} else {
$this->assertEquals(11 - ($sum % 11), (int)$controlCode);
}
}
}
}

0 comments on commit cb01380

Please sign in to comment.