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

Fix IBAN generator #590

Merged
merged 5 commits into from
Jun 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/Faker/Calculator/Iban.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Faker\Calculator;

class Iban
{
/**
* Generates IBAN Checksum
*
* @param string $iban
* @return string Checksum (numeric string)
*/
public static function checksum($iban)
{
// Move first four digits to end and set checksum to '00'
$checkString = substr($iban, 4) . substr($iban, 0, 2) . '00';

// Replace all letters with their number equivalents
$checkString = preg_replace_callback('/[A-Z]/', array('self','alphaToNumberCallback'), $checkString);

// Perform mod 97 and subtract from 98
$checksum = 98 - self::mod97($checkString);

return str_pad($checksum, 2, '0', STR_PAD_LEFT);
}

private static function alphaToNumberCallback($match)
{
return self::alphaToNumber($match[0]);
}

/**
* Converts letter to number
*
* @param string $char
* @return int
*/
public static function alphaToNumber($char)
{
return ord($char) - 55;
}

/**
* Calculates mod97 on a numeric string
*
* @param string $number Numeric string
* @param int
*/
public static function mod97($number)
{
$checksum = (int)$number[0];
for ($i = 1, $size = strlen($number); $i < $size; $i++) {
$checksum = (10 * $checksum + (int) $number[$i]) % 97;
}
return $checksum;
}

/**
* Checks whether an IBAN has a valid checksum
*
* @return boolean
*/
public static function isValid($iban)
{
return self::checksum($iban) === substr($iban, 2, 2);
}
}
44 changes: 16 additions & 28 deletions src/Faker/Provider/Payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Faker\Provider;

use Faker\Calculator\Iban;
use Faker\Calculator\Luhn;

class Payment extends Base
Expand Down Expand Up @@ -87,7 +88,7 @@ class Payment extends Base
'IL' => array(array('n', 3), array('n', 3), array('n', 13)),
'IS' => array(array('n', 4), array('n', 2), array('n', 6), array('n', 10)),
'IT' => array(array('a', 1), array('n', 5), array('n', 5), array('c', 12)),
'KW' => array(array('a', 4), array('c', 22)),
'KW' => array(array('a', 4), array('n', 22)),
'KZ' => array(array('n', 3), array('c', 13)),
'LB' => array(array('n', 4), array('c', 20)),
'LI' => array(array('n', 5), array('c', 12)),
Expand Down Expand Up @@ -115,7 +116,7 @@ class Payment extends Base
'SK' => array(array('n', 4), array('n', 6), array('n', 10)),
'SM' => array(array('a', 1), array('n', 5), array('n', 5), array('c', 12)),
'TN' => array(array('n', 2), array('n', 3), array('n', 13), array('n', 2)),
'TR' => array(array('n', 5), array('c', 1), array('c', 16)),
'TR' => array(array('n', 5), array('n', 1), array('c', 16)),
'VG' => array(array('a', 4), array('n', 16)),
);

Expand Down Expand Up @@ -213,7 +214,7 @@ public function creditCardDetails($valid = true)
protected static function iban($countryCode, $prefix = '', $length = null)
{
$countryCode = strtoupper($countryCode);
$format = !isset(static::$ibanFormats[$countryCode]) ? array() : static::$ibanFormats[$countryCode];
$format = !isset(static::$ibanFormats[$countryCode]) ? null : static::$ibanFormats[$countryCode];
if ($length === null) {
if ($format === null) {
$length = 24;
Expand All @@ -225,22 +226,19 @@ protected static function iban($countryCode, $prefix = '', $length = null)
}
}
}
if ($format === null) {
$format = array(array('n', $length));
}

$result = $prefix;
$length -= strlen($prefix);
$nextPart = array_shift($format);
if ($nextPart !== false) {
list($class, $groupCount) = $nextPart;
} else {
$class = 'n';
$groupCount = 0;
$expandedFormat = '';
foreach ($format as $item) {
list($class, $length) = $item;
$expandedFormat .= str_repeat($class, $length);
}
$groupCount = $nextPart === false ? 0 : $nextPart[1];
for ($i = 0; $i < $length; $i++) {
if ($nextPart !== false && $groupCount-- < 1) {
$nextPart = array_shift($format);
list($class, $groupCount) = $nextPart;
}

$result = $prefix;
$expandedFormat = substr($expandedFormat, strlen($result));
foreach (str_split($expandedFormat) as $class) {
switch ($class) {
default:
case 'c':
Expand All @@ -257,17 +255,7 @@ protected static function iban($countryCode, $prefix = '', $length = null)

$result = static::addBankCodeChecksum($result, $countryCode);

$countryNumber = 100 * (ord($countryCode[0])-55) + (ord($countryCode[1])-55);
$tempResult = $result . $countryNumber . '00';
// perform MOD97-10 checksum calculation
$checksum = (int) $tempResult[0];
for ($i = 1, $size = strlen($tempResult); $i < $size; $i++) {
$checksum = (10 * $checksum + (int) $tempResult[$i]) % 97;
}
$checksum = 98 - $checksum;
if ($checksum < 10) {
$checksum = '0'.$checksum;
}
$checksum = Iban::checksum($countryCode . '00' . $result);

return $countryCode . $checksum . $result;
}
Expand Down
Loading