Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

use Luhn to calculate ar_SA id numbers. #875

Merged
merged 11 commits into from
Oct 7, 2016
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ Fugiat non in itaque sunt nobis totam. Sed nesciunt est deleniti cumque alias. R
echo $faker->idNumber; // ID number
echo $faker->nationalIdNumber // Citizen ID number
echo $faker->foreignerIdNumber // Foreigner ID number
echo $faker->companyIdNumber // Company ID number
```

### `Faker\Provider\at_AT\Payment`
Expand Down
19 changes: 18 additions & 1 deletion src/Faker/Calculator/Luhn.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Faker\Calculator;

use Faker\Provider\Base as BaseProvider;
use InvalidArgumentException;

/**
* Utility class for generating Luhn checksum and validating a number
* Utility class for generating and validating Luhn numbers.
*
* Luhn algorithm is used to validate credit card numbers, IMEI numbers, and
* National Provider Identifier numbers.
Expand Down Expand Up @@ -55,4 +58,18 @@ public static function isValid($number)
{
return self::checksum($number) === 0;
}

/**
* Generate a Luhn compliant number.
*
* @param string $prefix
* @return string
*/
public static function generateLuhnNumber($partialValue)
{
if (!preg_match('/^\d+$/', $partialValue)) {
throw new InvalidArgumentException('Argument should be an integer.');
}
return $partialValue . Luhn::computeCheckDigit($partialValue);
}
}
11 changes: 11 additions & 0 deletions src/Faker/Provider/ar_SA/Company.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Faker\Provider\ar_SA;

use Faker\Calculator\Luhn;

class Company extends \Faker\Provider\Company
{
protected static $formats = array(
Expand Down Expand Up @@ -60,4 +62,13 @@ public function bs()

return join($result, ' ');
}

/**
* example 7001010101
**/
public static function companyIdNumber()
{
$partialValue = static::numerify(700 . str_repeat('#', 6));
return Luhn::generateLuhnNumber($partialValue);
}
}
54 changes: 12 additions & 42 deletions src/Faker/Provider/ar_SA/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Faker\Provider\ar_SA;

use Faker\Calculator\Luhn;

class Person extends \Faker\Provider\Person
{
protected static $maleNameFormats = array(
Expand Down Expand Up @@ -90,59 +92,27 @@ public static function prefix()
*/
public static function idNumber()
{
$firstDigit = static::numberBetween(1, 2);

do {
$number = $firstDigit.static::numerify('#########');
} while (!static::checkSum($number));

return $number;
$partialValue = static::numerify(
static::randomElement(array(1, 2)) . str_repeat('#', 8)
);
return Luhn::generateLuhnNumber($partialValue);
}

/**
* @example
* @example 1010101010
*/
public static function nationalIdNumber()
{
do {
$number = '1'.static::numerify('#########');
} while (!static::checkSum($number));

return $number;
$partialValue = static::numerify(1 . str_repeat('#', 8));
return Luhn::generateLuhnNumber($partialValue);
}

/**
* @example
* @example 2010101010
*/
public static function foreignerIdNumber()
{
do {
$number = '2'.static::numerify('#########');
} while (!static::checkSum($number));

return $number;
}

/**
* Check sum the number.
* @param $number
*
* @return bool
*/
protected static function checkSum($number)
{
$sum = 0;
$nums = str_split($number);

for ($i = 0; $i < 10; $i++) {
if ($i % 2 == 0) {
$s = $nums[$i] * 2;
$sum += $s % 10 + floor($s / 10);
} else {
$sum += $nums[$i];
}
}

return ($sum % 10 == 0);
$partialValue = static::numerify(2 . str_repeat('#', 8));
return Luhn::generateLuhnNumber($partialValue);
}
}
9 changes: 9 additions & 0 deletions test/Faker/Calculator/LuhnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,13 @@ public function testIsValid($number, $isValid)
{
$this->assertEquals($isValid, Luhn::isValid($number));
}

/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Argument should be an integer.
*/
public function testGenerateLuhnNumberWithInvalidPrefix()
{
Luhn::generateLuhnNumber('abc');
}
}