计算IBAN帐号

时间:2014-01-12 16:47:18

标签: php

我找到了这个维基页面: http://en.wikipedia.org/wiki/IBAN#Validating_the_IBAN

我按照这样的步骤:

$iban = 'GB82WEST12345698765432';

$bankname      = substr($iban, 0, 4);
$accountnumber = substr($iban, 4);

$country = $this->convertToNumber($bankname);

$number = ($accountnumber . $country);
$area   = substr($number, 0, 4);

$accountnumber = substr($number, 4);

$number = $this->convertToNumber($area) . $accountnumber;

var_dump('3214282912345698765432161182');

var_dump($number);

所以现在我和示例中的号码相同。输出:

string 'GB82WEST12345698765432' (length=22)

string '3214282912345698765432161182' (length=28)

string '3214282912345698765432161182' (length=28)

如果我现在3214282912345698765432161182 mod 97 = 1

var_dump($number % 97);

我得到:int 78

他们得到结果1。我做错了什么?

2 个答案:

答案 0 :(得分:2)

wiki建议langague的算法不支持bignumber(它需要220bits整数):

  1. 从D的最左边数字开始,使用前9位数字构建一个数字,并将其称为N。
  2. 计算N mod 97。
  3. 通过将上面的结果(步骤2)与D的下一个7位数连接起来构造一个新的9位数N.如果D中剩余的数字少于7位但至少有一位,那么构造一个新的N,它将具有小于9位,从上面的结果(步骤2)开始,接着是D
  4. 的剩余数字
  5. 重复步骤2-3,直到处理完D的所有数字
  6. 在php中编写此代码,结果为1

    <?php
    $iban = "3214282912345698765432161182";
    
    $first = substr($iban, 0, 9);
    $array = str_split(substr($iban, 9),7);
    
    $result = $first % 97;
    foreach ($array as &$value) {
        $result = intval( strval($result) .  $value) % 97;
    }
    
    if ($result == 1) {
        echo "IBAN:$iban is valid";
    } else {
        echo "IBAN:$iban invalid remainder:$result";
    }
    
    ?>
    

    运行测试:http://ideone.com/1XNE2b

      

    IBAN:3214282912345698765432161182有效

答案 1 :(得分:1)

不幸的是,PHP严重处理了大量数据。 您所需要的只是将数字存储为任意数字并使用正确的PHP功能。 请检查BCMath。 示例很清楚:

php > var_dump(bcmod('3214282912345698765432161182',(int)97));
string(1) "1"

为了这个缘故,你应该将庞大的数字作为字符串传递,这样PHP就不会破坏它,在这种情况下,结果将是“1”,如果你将大数字作为int传递 - 它将在到达bcmod()之前变为浮动,结果你最终会收到“0”。