<?php
    
/**
    * Bir hesap numrasının geçerli IBAN formatında olup olmadını kontrol eder.
    * "Registration Authority for ISO 13616" dökümanı doğrultusunda yazılmıştur.
    * 
    * NOT:
    * Tüm ülkeler için maksimum IBAN uzunluğu 31 karakter olabilir
    * TÜRKİYE için maksimum IBAN uzunluğu 26 karakter olabilir
    * 
    * yazar: Erhan BURHAN
    * email: eburhan[at]gmail[dot]com
    * adres: www.eburhan.com
    */
    
function is_IBAN($iban '')
    {
        
// ilk önce formatı kontrol ediyoruz
        
if( ! is_IBAN_format($iban) )
            return 
false;

        
// şimdi de algoritmayla kontrol ediyoruz
        
$iban substr($iban422).substr($iban,0,4);
        
$iban str_replace(
            array(
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'),
            array(
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35), $iban
        
);

        
// oluşan sayıyı 5'li basamaklara ayırıyoruz
        
$iban str_split($iban5);
        
$max count($iban) - 1// en büyük indis sayısı
        
$i 0;

        
// 5 parçaya ayırdığımız sayıların tek tek modunu alıyoruz. Yararlandığım kaynak:
        // http://en.wikipedia.org/wiki/International_Bank_Account_Number#Calculating_the_modulus_of_a_large_number
        
while ($i <= $max) {
            
$kalan $iban[$i] % 97;
            if( ++
$i $max ) break; // önceden arttırmaya dikkat !
            
$iban[$i] = $kalan.$iban[$i];
        }

        return (
$kalan === 1);
    }

    function 
is_IBAN_format($iban '')
    {
        
// son RegEx güncellemesi: Ocak 2010 \\
        
$ibanRegex = array
        (
            
/* 01 */ 'AL' => '/^AL\d{2}\d{8}[A-Za-z0-9]{16}$/',
            
/* 02 */ 'AD' => '/^AD\d{2}\d{4}\d{4}[A-Za-z0-9]{12}$/',
            
/* 03 */ 'AT' => '/^AT\d{2}\d{5}\d{11}$/',
            
/* 04 */ 'BE' => '/^BE\d{2}\d{3}\d{7}\d{2}$/',
            
/* 05 */ 'BA' => '/^BA\d{2}\d{3}\d{3}\d{8}\d{2}$/',
            
/* 06 */ 'BG' => '/^BG\d{2}[A-Z]{4}\d{4}\d{2}[A-Za-z0-9]{8}$/',
            
/* 07 */ 'HR' => '/^HR\d{2}\d{7}\d{10}$/',
            
/* 08 */ 'CY' => '/^CY\d{2}\d{3}\d{5}[A-Za-z0-9]{16}$/',
            
/* 09 */ 'CZ' => '/^CZ\d{2}\d{4}\d{6}\d{10}$/',

            
/* 10 */ 'DK' => '/^DK\d{2}\d{4}\d{9}\d{1}$/',
            
/* 10 */ 'FO' => '/^FO\d{2}\d{4}\d{9}\d{1}$/',
            
/* 10 */ 'GL' => '/^GL\d{2}\d{4}\d{9}\d{1}$/',

            
/* 11 */ 'EE' => '/^EE\d{2}\d{2}\d{2}\d{11}\d{1}$/',
            
/* 12 */ 'FI' => '/^FI\d{2}\d{6}\d{7}\d{1}$/',

            
/* 13 */ 'FR' => '/^FR\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 13 */ 'PF' => '/^PF\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 13 */ 'TF' => '/^TF\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 13 */ 'YT' => '/^YT\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 13 */ 'NC' => '/^NC\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 13 */ 'PM' => '/^PM\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 13 */ 'WF' => '/^WF\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
    
            
/* 14 */ 'DE' => '/^DE\d{2}\d{8}\d{10}$/',
            
/* 15 */ 'GI' => '/^GI\d{2}[A-Z]{4}[A-Za-z0-9]{15}$/',
            
/* 16 */ 'GR' => '/^GR\d{2}\d{3}\d{4}[A-Za-z0-9]{16}$/',
            
/* 17 */ 'HU' => '/^HU\d{2}\d{3}\d{4}\d{1}\d{15}\d{1}$/',
            
/* 18 */ 'IS' => '/^IS\d{2}\d{4}\d{2}\d{6}\d{10}$/',
            
/* 19 */ 'IE' => '/^IE\d{2}[A-Z]{4}\d{6}\d{8}$/',
            
/* 20 */ 'IL' => '/^IL\d{2}\d{3}\d{3}\d{13}$/',
            
/* 21 */ 'IT' => '/^IT\d{2}[A-Z]{1}\d{5}\d{5}[A-Za-z0-9]{12}$/',
            
/* 22 */ 'LV' => '/^LV\d{2}[A-Z]{4}[A-Za-z0-9]{13}$/',
            
/* 23 */ 'LB' => '/^LB\d{2}\d{4}[A-Za-z0-9]{20}$/',
            
/* 24 */ 'LI' => '/^LI\d{2}\d{5}[A-Za-z0-9]{12}$/',
            
/* 25 */ 'LT' => '/^LT\d{2}\d{5}\d{11}$/',
            
/* 26 */ 'LU' => '/^LU\d{2}\d{3}[A-Za-z0-9]{13}$/',
            
/* 27 */ 'MK' => '/^MK\d{2}\d{3}[A-Za-z0-9]{10}\d{2}$/',
            
/* 28 */ 'MT' => '/^MT\d{2}[A-Z]{4}\d{5}[A-Za-z0-9]{18}$/',
            
/* 29 */ 'MU' => '/^MU\d{2}[A-Z]{4}\d{2}\d{2}\d{12}\d{3}[A-Z]{3}$/',
            
/* 30 */ 'MC' => '/^MC\d{2}\d{5}\d{5}[A-Za-z0-9]{11}\d{2}$/',
            
/* 31 */ 'ME' => '/^ME\d{2}\d{3}\d{13}\d{2}$/',
            
/* 32 */ 'NL' => '/^NL\d{2}[A-Z]{4}\d{10}$/',
            
/* 33 */ 'NO' => '/^NO\d{2}\d{4}\d{6}\d{1}$/',
            
/* 34 */ 'PL' => '/^PL\d{2}\d{8}\d{1,16}$/',
            
/* 35 */ 'PT' => '/^PT\d{2}\d{4}\d{4}\d{11}\d{2}$/',
            
/* 36 */ 'RO' => '/^RO\d{2}[A-Z]{4}[A-Za-z0-9]{16}$/',
            
/* 37 */ 'SM' => '/^SM\d{2}[A-Z]{1}\d{5}\d{5}[A-Za-z0-9]{12}$/',
            
/* 38 */ 'SA' => '/^SA\d{2}\d{2}[A-Za-z0-9]{18}$/',
            
/* 39 */ 'RS' => '/^RS\d{2}\d{3}\d{13}\d{2}$/',
            
/* 40 */ 'SK' => '/^SK\d{2}\d{4}\d{6}\d{10}$/',
            
/* 41 */ 'SI' => '/^SI\d{2}\d{5}\d{8}\d{2}$/',
            
/* 42 */ 'ES' => '/^ES\d{2}\d{4}\d{4}\d{1}\d{1}\d{10}$/',
            
/* 43 */ 'SE' => '/^SE\d{2}\d{3}\d{16}\d{1}$/',
            
/* 44 */ 'CH' => '/^CH\d{2}\d{5}[A-Za-z0-9]{12}$/',
            
/* 45 */ 'TN' => '/^TN59\d{2}\d{3}\d{13}\d{2}$/',
            
/* 46 */ 'TR' => '/^TR\d{2}\d{5}[A-Za-z0-9]{1}[A-Za-z0-9]{16}$/',
            
/* 47 */ 'GB' => '/^GB\d{2}[A-Z]{4}\d{6}\d{8}$/'
        
);

        
$ulke substr((string) $iban02);

        if( ! isset(
$ibanRegex[$ulke]) )
            return 
false;

        if( 
preg_match($ibanRegex[$ulke], $iban) === )
            return 
false;

        return 
true;
    }    
?>