验证 IBAN PHP

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20983339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:43:32  来源:igfitidea点击:

Validate IBAN PHP

phpvalidationiban

提问by Peter Fox

As designing a new platform we tried to integrate the IBAN numbers. We have to make sure that the IBAN is validated and the IBAN stored to the database is always correct. So what would be a proper way to validate the number?

在设计新平台时,我们尝试整合 IBAN 号码。我们必须确保 IBAN 得到验证并且存储到数据库中的 IBAN 始终正确。那么验证数字的正确方法是什么?

回答by Peter Fox

As the logic was explained in my other question I've tried to create a function myself. Based on the logic explained in the wikipedia article find a proper function below. Country specific validation.

由于在我的另一个问题中解释了逻辑,我尝试自己创建一个函数。根据维基百科文章中解释的逻辑,在下面找到一个合适的函数。特定国家/地区的验证。

Will it fit the

是否适合

http://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN

http://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN

function checkIBAN($iban)
{
    $iban = strtolower(str_replace(' ','',$iban));
    $Countries = array('al'=>28,'ad'=>24,'at'=>20,'az'=>28,'bh'=>22,'be'=>16,'ba'=>20,'br'=>29,'bg'=>22,'cr'=>21,'hr'=>21,'cy'=>28,'cz'=>24,'dk'=>18,'do'=>28,'ee'=>20,'fo'=>18,'fi'=>18,'fr'=>27,'ge'=>22,'de'=>22,'gi'=>23,'gr'=>27,'gl'=>18,'gt'=>28,'hu'=>28,'is'=>26,'ie'=>22,'il'=>23,'it'=>27,'jo'=>30,'kz'=>20,'kw'=>30,'lv'=>21,'lb'=>28,'li'=>21,'lt'=>20,'lu'=>20,'mk'=>19,'mt'=>31,'mr'=>27,'mu'=>30,'mc'=>27,'md'=>24,'me'=>22,'nl'=>18,'no'=>15,'pk'=>24,'ps'=>29,'pl'=>28,'pt'=>25,'qa'=>29,'ro'=>24,'sm'=>27,'sa'=>24,'rs'=>22,'sk'=>24,'si'=>19,'es'=>24,'se'=>24,'ch'=>21,'tn'=>24,'tr'=>26,'ae'=>23,'gb'=>22,'vg'=>24);
    $Chars = array('a'=>10,'b'=>11,'c'=>12,'d'=>13,'e'=>14,'f'=>15,'g'=>16,'h'=>17,'i'=>18,'j'=>19,'k'=>20,'l'=>21,'m'=>22,'n'=>23,'o'=>24,'p'=>25,'q'=>26,'r'=>27,'s'=>28,'t'=>29,'u'=>30,'v'=>31,'w'=>32,'x'=>33,'y'=>34,'z'=>35);

    if(strlen($iban) == $Countries[substr($iban,0,2)]){

        $MovedChar = substr($iban, 4).substr($iban,0,4);
        $MovedCharArray = str_split($MovedChar);
        $NewString = "";

        foreach($MovedCharArray AS $key => $value){
            if(!is_numeric($MovedCharArray[$key])){
                $MovedCharArray[$key] = $Chars[$MovedCharArray[$key]];
            }
            $NewString .= $MovedCharArray[$key];
        }

        if(bcmod($NewString, '97') == 1)
        {
            return true;
        }
    }
    return false;
}

回答by Сухой27

Slight modification of @PeterFox answer including support for bcmod()when bcmathis not available,

对@PeterFox 答案的轻微修改,包括对bcmod()何时bcmath不可用的支持,

<?php

function isValidIBAN ($iban) {

  $iban = strtolower($iban);
  $Countries = array(
    'al'=>28,'ad'=>24,'at'=>20,'az'=>28,'bh'=>22,'be'=>16,'ba'=>20,'br'=>29,'bg'=>22,'cr'=>21,'hr'=>21,'cy'=>28,'cz'=>24,
    'dk'=>18,'do'=>28,'ee'=>20,'fo'=>18,'fi'=>18,'fr'=>27,'ge'=>22,'de'=>22,'gi'=>23,'gr'=>27,'gl'=>18,'gt'=>28,'hu'=>28,
    'is'=>26,'ie'=>22,'il'=>23,'it'=>27,'jo'=>30,'kz'=>20,'kw'=>30,'lv'=>21,'lb'=>28,'li'=>21,'lt'=>20,'lu'=>20,'mk'=>19,
    'mt'=>31,'mr'=>27,'mu'=>30,'mc'=>27,'md'=>24,'me'=>22,'nl'=>18,'no'=>15,'pk'=>24,'ps'=>29,'pl'=>28,'pt'=>25,'qa'=>29,
    'ro'=>24,'sm'=>27,'sa'=>24,'rs'=>22,'sk'=>24,'si'=>19,'es'=>24,'se'=>24,'ch'=>21,'tn'=>24,'tr'=>26,'ae'=>23,'gb'=>22,'vg'=>24
  );
  $Chars = array(
    'a'=>10,'b'=>11,'c'=>12,'d'=>13,'e'=>14,'f'=>15,'g'=>16,'h'=>17,'i'=>18,'j'=>19,'k'=>20,'l'=>21,'m'=>22,
    'n'=>23,'o'=>24,'p'=>25,'q'=>26,'r'=>27,'s'=>28,'t'=>29,'u'=>30,'v'=>31,'w'=>32,'x'=>33,'y'=>34,'z'=>35
  );

  if (strlen($iban) != $Countries[ substr($iban,0,2) ]) { return false; }

  $MovedChar = substr($iban, 4) . substr($iban,0,4);
  $MovedCharArray = str_split($MovedChar);
  $NewString = "";

  foreach ($MovedCharArray as $k => $v) {

    if ( !is_numeric($MovedCharArray[$k]) ) {
      $MovedCharArray[$k] = $Chars[$MovedCharArray[$k]];
    }
    $NewString .= $MovedCharArray[$k];
  }
  if (function_exists("bcmod")) { return bcmod($NewString, '97') == 1; }

  // http://au2.php.net/manual/en/function.bcmod.php#38474
  $x = $NewString; $y = "97";
  $take = 5; $mod = "";

  do {
    $a = (int)$mod . substr($x, 0, $take);
    $x = substr($x, $take);
    $mod = $a % $y;
  }
  while (strlen($x));

  return (int)$mod == 1;
}

回答by esserj

The accepted answer is not the preferred way of validation, the specificationdictates the following:

接受的答案不是首选的验证方式,规范规定了以下内容:

 1. Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
 2. Replace the two check digits by 00 (e.g. GB00 for the UK)
 3. Move the four initial characters to the end of the string
 4. Replace the letters in the string with digits, expanding the string as necessary, such that A or a = 10,
    B or b = 11, and Z or z = 35. Each alphabetic character is therefore replaced by 2 digits
 5. Convert the string to an integer (i.e. ignore leading zeroes)
 6. Calculate mod-97 of the new number, which results in the remainder
 7. Subtract the remainder from 98, and use the result for the two check digits. If the result is a single digit
   number, pad it with a leading 0 to make a two-digit number

I've written a class that validates, formats and parses strings according to the spec, hope this helps save some the time to roll their own. Code found here:

我编写了一个根据规范验证、格式化和解析字符串的类,希望这有助于节省一些时间来推出自己的。代码在这里找到:

https://gist.github.com/esserj/a54ffd11182417cf920d

https://gist.github.com/esserj/a54ffd11182417cf920d

回答by SVetter

Sorry, I can not yet comment due to low Rep, so the new link to user3733632s answer:

抱歉,由于 Rep 低,我还不能发表评论,所以新的 user3733632s 链接回答:

https://github.com/globalcitizen/php-iban

https://github.com/globalcitizen/php-iban

(the project is no longer hosted at google code as of March 2015, and the project will get a new version after some cleanup.)

(截至 2015 年 3 月,该项目不再托管在 google code,该项目将在一些清理后获得新版本。)

回答by jhabai

top rated function does NOT work.

最受好评的功能不起作用。

Just try a string with '%' in it...

只需尝试一个带有 '%' 的字符串...

I'm using this one :

我正在使用这个:

function checkIBAN($iban) {

// Normalize input (remove spaces and make upcase)
$iban = strtoupper(str_replace(' ', '', $iban));

if (preg_match('/^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$/', $iban)) {
    $country = substr($iban, 0, 2);
    $check = intval(substr($iban, 2, 2));
    $account = substr($iban, 4);

    // To numeric representation
    $search = range('A','Z');
    foreach (range(10,35) as $tmp)
        $replace[]=strval($tmp);
    $numstr=str_replace($search, $replace, $account.$country.'00');

    // Calculate checksum
    $checksum = intval(substr($numstr, 0, 1));
    for ($pos = 1; $pos < strlen($numstr); $pos++) {
        $checksum *= 10;
        $checksum += intval(substr($numstr, $pos,1));
        $checksum %= 97;
    }

    return ((98-$checksum) == $check);
} else
    return false;
}

回答by user3733632

Google Code hosts a project of an open source php-iban validator: https://code.google.com/p/php-iban/

Google Code 托管了一个开源 php-iban 验证器项目:https: //code.google.com/p/php-iban/

回答by Fabrice G

This function check the IBAN and need GMP activate http://php.net/manual/en/book.gmp.php.

此功能检查 IBAN 并需要 GMP 激活http://php.net/manual/en/book.gmp.php

function checkIban($string){
    $to_check = substr($string, 4).substr($string, 0,4);
    $converted = '';
    for ($i = 0; $i < strlen($to_check); $i++){
        $char = strtoupper($to_check[$i]);
        if(preg_match('/[0-9A-Z]/',$char)){
            if(!preg_match('/\d/',$char)){
                $char = ord($char)-55;
            }
            $converted .= $char;
        }
    }
    return (strlen($converted) > 0 && gmp_strval(gmp_mod($converted, "97")) == 1);
}

enjoy !

请享用 !

回答by Aivaras Godliauskas

I found this solution in cakephp 3.7 validation class. Plain beautiful php realization.

我在cakephp 3.7 验证类中找到了这个解决方案。简单漂亮的 php 实现。

/**
 * Check that the input value has a valid International Bank Account Number IBAN syntax
 * Requirements are uppercase, no whitespaces, max length 34, country code and checksum exist at right spots,
 * body matches against checksum via Mod97-10 algorithm
 *
 * @param string $check The value to check
 *
 * @return bool Success
 */
public static function iban($check)
{
    if (!preg_match('/^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$/', $check)) {
        return false;
    }

    $country = substr($check, 0, 2);
    $checkInt = intval(substr($check, 2, 2));
    $account = substr($check, 4);
    $search = range('A', 'Z');
    $replace = [];
    foreach (range(10, 35) as $tmp) {
        $replace[] = strval($tmp);
    }
    $numStr = str_replace($search, $replace, $account . $country . '00');
    $checksum = intval(substr($numStr, 0, 1));
    $numStrLength = strlen($numStr);
    for ($pos = 1; $pos < $numStrLength; $pos++) {
        $checksum *= 10;
        $checksum += intval(substr($numStr, $pos, 1));
        $checksum %= 97;
    }

    return ((98 - $checksum) === $checkInt);
}

回答by Andrei Ivanouski

Latest countires list (2020-04-07):

最新国家名单(2020-04-07):

$countries = [
    'ad' => 24,
    'ae' => 23,
    'al' => 28,
    'at' => 20,
    'az' => 28,
    'ba' => 20,
    'be' => 16,
    'bg' => 22,
    'bh' => 22,
    'br' => 29,
    'by' => 28,
    'ch' => 21,
    'cr' => 21,
    'cy' => 28,
    'cz' => 24,
    'de' => 22,
    'dk' => 18,
    'do' => 28,
    'ee' => 20,
    'es' => 24,
    'fi' => 18,
    'fo' => 18,
    'fr' => 27,
    'gb' => 22,
    'ge' => 22,
    'gi' => 23,
    'gl' => 18,
    'gr' => 27,
    'gt' => 28,
    'hr' => 21,
    'hu' => 28,
    'ie' => 22,
    'il' => 23,
    'is' => 26,
    'it' => 27,
    'jo' => 30,
    'kw' => 30,
    'kz' => 20,
    'lb' => 28,
    'li' => 21,
    'lt' => 20,
    'lu' => 20,
    'lv' => 21,
    'mc' => 27,
    'md' => 24,
    'me' => 22,
    'mk' => 19,
    'mr' => 27,
    'mt' => 31,
    'mu' => 30,
    'nl' => 18,
    'no' => 15,
    'pk' => 24,
    'pl' => 28,
    'ps' => 29,
    'pt' => 25,
    'qa' => 29,
    'ro' => 24,
    'rs' => 22,
    'sa' => 24,
    'se' => 24,
    'si' => 19,
    'sk' => 24,
    'sm' => 27,
    'tl' => 23,
    'tn' => 24,
    'tr' => 26,
    'ua' => 29,
    'vg' => 24,
    'xk' => 20,
];

https://ru.wikipedia.org/wiki/IBAN

https://ru.wikipedia.org/wiki/IBAN