2014-01-07 23 views
6

Bei der Entwicklung einer neuen Plattform haben wir versucht, die IBAN-Nummern zu integrieren. Wir müssen sicherstellen, dass die IBAN validiert ist und die IBAN in der Datenbank immer korrekt ist. Was wäre ein geeigneter Weg, die Nummer zu validieren?IBAN validieren PHP

+0

Die meisten Länder haben keine länderspezifische Prüfung, wie empfohlen. –

+1

Die lustige Sache ist: Wenn Sie auf @MarcinOrlowski lmfgtfy Link klicken, erscheint diese Frage als das erste Suchergebnis;) –

+0

@FrederikKammer vielleicht ist es wegen dieser Verbindung an erster Stelle, also eine Art Endlosschleife in freier Wildbahn:) –

Antwort

25

Wie die Logik in meiner anderen Frage erklärt wurde, habe ich versucht, eine Funktion selbst zu erstellen. Basierend auf der im Wikipedia-Artikel erläuterten Logik finden Sie unten eine ordnungsgemäße Funktion. Länderspezifische Validierung

Wird es passen die

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; 
     } 
     else{ 
      return FALSE; 
     } 
    } 
    else{ 
     return FALSE; 
    } 
} 
+0

Schön! Das einzige, was Sie vermisst haben, die $ NewString-Variable auf eine leere Zeichenfolge zu initialisieren, wird andernfalls einen Fehler auslösen. – sucotronic

+0

@sucotronic hat gerade die Antwort aktualisiert. –

+0

@PeterFox Woher haben Sie die Liste der Länder und deren IBAN-Längen, und enthält die Liste jedes Land? – BadHorsie

3

leichte Modifikation @PeterFox Antwort einschließlich der Unterstützung für bcmod() wenn bcmath ist nicht verfügbar,

<?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; 
} 
4

Sorry, kann ich noch nicht kommentieren aufgrund der niedrigen Rep, so dass die neue Verbindung Antwort auf user3733632s:

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

(das Projekt wird nicht mehr bei Google Code gehostet ab März 2015 und das Projekt wird nach einer Aufräumung eine neue Version bekommen.)

+1

Diese Bibliothek sieht nicht gut aus. Es ist schlecht aufgebaut - es gibt eine Klasse, aber es ist kein Namespace, daher kann es nicht automatisch geladen werden. Alle Methoden delegieren an prozedurale Funktionen. Am wichtigsten ist, dass es keine Tests gibt, was für alles, was mit Finanztransaktionen zusammenhängt, absolut notwendig ist. – pfrenssen

0

Top bewertete Funktion funktioniert nicht.

Versuchen Sie einfach einen String mit ‚%‘ drin ...

Ich verwende dieses:

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; 
} 
3

Die akzeptierte Antwort ist nicht die bevorzugte Art und Weise der Validierung, die specification diktiert die folgende:

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 

ich habe eine Klasse geschrieben, die, Formate und parst Strings gemäß der Spezifikation validiert, hoffe, das hilft etwas Zeit zu sparen, ihre eigene Rolle. Code finden Sie hier:

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

+0

Das ist einfach nicht wahr. Was Sie tun, ist die Berechnung der Prüfziffern, das ist völlig in Ordnung, aber nicht notwendig, wenn Sie nur die IBAN validieren wollen. Wenn Sie die Prüfziffern nicht auf Null zurücksetzen und am Ende nicht von 98 subtrahieren, erhalten Sie 1, wenn die IBAN gültig ist. Das ist ausreichend, wenn Sie nur verifizieren möchten. – inta

0

dieser Funktion wird die IBAN überprüfen und müssen GMP http://php.net/manual/en/book.gmp.php aktivieren.

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); 
} 

viel Spaß!