Arka Roy

Validate IBAN in PHP

International Bank Account Number (IBAN) is an international standard for identifying account numbers. How can we make sure that an user enters a valid IBAN?

Validation Algorithm

An IBAN is validated by converting it into an integer and performing a basic mod-97 operation (as described in ISO 7064) on it. If the IBAN is valid, the remainder equals 1. The algorithm of IBAN validation is as follows:

  • Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
  • Move the four initial characters to the end of the string
  • Replace each letter in the string with two digits, thereby expanding the string, where A = 10, B = 11, ..., Z = 35
  • Interpret the string as a decimal integer and compute the remainder of that number on division by 97

If the remainder is 1, the check digit test is passed and the IBAN might be valid.

Implementation

The algorithm can be implemented in PHP in the following way.

<?php

/**
 * Check whether the iban is valid
 * 
 * @param string $iban Iban to check
 * @return boolean true if valid iban, false otherwise
 */
function is_iban_valid($iban)
{
    $iban = strtolower(preg_replace('/\s+/', '', $iban));
    $countries = ['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];
    if (strlen($iban) < 2) {
        return false;
    }
    $country = substr($iban, 0, 2);
    if (isset($countries[$country]) && strlen($iban) == $countries[$country]) {
        $reordered = substr($iban, 4) . substr($iban, 0, 4);
        $chars = str_split($reordered);
        $converted = '';

        foreach ($chars as $key => $value) {
            if (!is_numeric($value)) {
                $chars[$key] = mb_ord($value, 'utf8') - 87;
            }
            $converted .= $chars[$key];
        }
        if (bcmod($converted, '97') == 1) {
            return true;
        }
    }
    return false;
}

If you want to know more about IBAN and/or how the system works around it, check Wikipedia.

Other Articles

Unparse a Parsed URL in PHP

PHP has a nice and very useful method parse_url to parse and split the url into applicable url components and return the list of component as associative array. But sometimes, you may need to reverse the process.