Publicado por & archivado en PHP, Programación.

Desde febrero de 2014 es obligatorio el uso de cuentas en formato IBAN (International Bank Account Number), y aunque casi todos los bancos aun admiten el antiguo formato, antes o después nos encontraremos con la necesidad de convertir las cuentas en formato CCC.

Aquí puedes convertir una cuenta bancaria a IBAN y validar si es correcta.

Para saber como se hace la conversión y validación de las cuentas IBAN y ver un ejemplo de programación en PHP, sigue leyendo.

Las cuentas IBAN se calculan añadiendo el código ISO 3166-1 del país junto a un código de control de dos cifras delante del BBAN (Basic Bank Account Number), que en España se corresponde con los 20 dígitos del CCC (Código Cuenta Cliente).

 

Para calcular el dígito de control del IBAN se añade el código ISO 3166-1 del país y dos ceros, se divide el número resultante entre 97 y el resto se resta de 98.

 

Aunque la norma ISO 3166-1 tiene especificado un código numérico, no es ese el que debe usarse, sino el conocido código alfa-2, que en el caso de España es ES.

 

Para convertir el código alfa-2 de la ISO 3166-1 se usa la siguiente correlación numérica con las letras:

A = 10 F = 15 K = 20 P = 25 U = 30 Z = 35
B = 11 G = 16 L = 21 Q = 26 V = 31
C = 12 H = 17 M = 22 R = 27 W = 32
D = 13 I = 18 N = 23 S = 28 X = 33
E = 14 J = 19 O = 24 T = 29 Y = 34

 

 

De esta forma, para el cálculo de España (ES), se utilizaría:

E=14
S=28

A esto se le añaden dos ceros, por lo que el código para España sería 142800.

 

Es decir, se divide el número resultante de concatenar los 20 dígitos de la cuenta bancaria con 142800 entre 97 y luego se resta a 98 el resto de esa división.

 

Hasta aquí todo fácil, pero hay un problema y es que el número resultante de sumar los 20 dígitos de la cuenta corriente, más los 4 del código ISO 3166-1, más dos ceros, es un número de 26 dígitos, demasiado grande para operar normalmente con las funciones de programación habituales, de esta forma, si lo intentamos con este código PHP:


echo 98 - (12341234161234567890142800 % 97);

No será capaz de manejar un número tan grande y devolverá siempre 0 de resto.

Esto empeora aun más con cuentas de otros países, ya que el BBAN puede tener hasta 34 caracteres alfanuméricos, lo que podría dar un número realmente gigante, por ejemplo un código de 34 caracteres con 4 letras nos daría un número de 48 dígitos, ya que todas las letras deben convertirse por su correspondiente número según la tabla anterior.

 

Para hacer semejante división hay varias soluciones, la más fácil es usar la librería GMP «GNU Multiple Precision Arithmetic Library», para cálculos con precisión arbitraria (bignum), que permite operar con números de cualquier tamaño mientras no se agote la memoria del sistema.

Ahora ya podemos calcular el IBAN de una CCC:


/**
 * @name Ejemplo de conversor de CCC a IBAN
 * @copyright (c)2015 Intervia IT
 * @link http://intervia.com/doc/convertir-cuentas-de-formato-ccc-a-iban/
 * @license MIT http://opensource.org/licenses/MIT
 */


$es_iso = '142800'; //Código ISO ES + 00
$ccc = '12341234161234567890'; //Cuenta de ejemplo
$bban_es = $ccc.$es_iso; //CCC + ES + 00

 /*
  * Hace la división del número de cuenta concatenado con el código de país entre 97
  * Obtiene el resto de esta división y lo resta de 98 para obtener el dígito de control
  * 
  * Se usa GMP "GNU Multiple Precision Arithmetic Library", para cálculos con 
  * precisión arbitraria (bignum), que permite operar con números de cualquier tamaño
  * mientras no se agote la memoria del sistema.
  * 
  * gmp_init genera el recurso a partir del número con la base indicada
  * gmp_mod calcula el resto de la división (modulo operation)
  * gmp_intval convierte un recurso GMP en un entero
  * 
  */
$ibandc = str_pad(98 - gmp_intval(gmp_mod(gmp_init($bban_es, 10),'97')),2,0,STR_PAD_LEFT);

//Crea el código IBAN concatenando código de país, DC IBAN y cuenta
$iban = 'ES'.$ibandc.$ccc;

//Para mostrar el IBAN en bloques de 4 dígitos
$iban2 = substr($iban,0,4).' '.
 substr($iban,4,4).' '.
 substr($iban,8,4).' '.
 substr($iban,12,4).' '.
 substr($iban,16,4).' '.
 substr($iban,20,4).' '.
 substr($iban,24,4);

echo 'IBAN formato electrónico: '.$iban.'<br>';
echo 'IBAN formato impreso: '.$iban2;

Esto devuelve:

IBAN formato electrónico: ES7712341234161234567890
IBAN formato impreso: ES77 1234 1234 1612 3456 7890

Este ejemplo es válido para cuentas bancarias españolas y este proceso además, no verifica la validez de la cuenta BBAN (CCC), que tiene su propio dígito de control.

 

Para validar un DC de una cuenta española, se usan dos números, el primero resultado de concatenar el código del banco y de la sucursal y el segundo el número de cuenta, entre estos dos grupos está el dígito de control de dos dígitos, el primero valida el banco y sucursal y el segundo la cuenta.

 

Los dos números del dígito de control, se obtienen multiplicado cada dígito del número de banco+cuenta y del número de cuenta, por un número arbitrario, sumando el resultado de las multiplicaciones de todos los dígitos de cada uno de los dos números y restando de 11 el resto de dividir la suma de los números entre 11. Si el número resultante es de un dígito se usa directamente, si tiene dos dígitos, si es 10 vale 1, y si es 11 vale 0.

Empezando por las unidades (el dígito de la derecha), deben multiplicarse cada uno por los siguientes números.

 

Para los 8 dígitos de concatenar el código del banco y de la sucursal:

6, 3, 7, 9, 10, 5, 8, 4

 

Para los 10 dígitos del número de cuenta:

6, 3, 7, 9, 10, 5, 8, 4, 2, 1

 

Por ejemplo, para la cuenta 1234 1234 16 1234567890:

Número 1 = 12341234
Número 2 = 1234567890

Número 1 = 4×6 + 3×3 + 2×7 + 1×9 + 4×10 + 3×5 + 2×8 + 1×4 = 131
Resto de 131 / 11 = 10
11 – 10 = 1, por lo que el primer dígito es 1

Número 2 = 0x6 + 9×3 + 8×7 + 7×9 + 6×10 + 5×5 + 4×8 + 3×4 + 2×2 + 1×1 = 280
Resto de 280 / 11 = 5
11- 5 = 6, por lo que el segundo dígito es 6

Así, el dígito de control debe ser 16.

 

 

Un ejemplo de validación de cuentas CCC en PHP:


/**
 * @name Ejemplo de validación de cuentas bancarias CCC
 * @copyright (c)2015 Intervia IT
 * @link http://intervia.com/doc/convertir-cuentas-de-formato-ccc-a-iban/
 * @license MIT http://opensource.org/licenses/MIT
 */

/*
 * ******************
 * Validación del CCC
 * ******************
 */

//Inicializa la variable de error
$error = 0;

//Suma los dígitos del banco y la sucursal multiplicados por sus pesos
$dc1s = 0;
$dc1s += $ccc[0] * 4;
$dc1s += $ccc[1] * 8;
$dc1s += $ccc[2] * 5;
$dc1s += $ccc[3] * 10;
$dc1s += $ccc[4] * 9;
$dc1s += $ccc[5] * 7;
$dc1s += $ccc[6] * 3;
$dc1s += $ccc[7] * 6;

//El primer DC es 11 menos el resto de la anteror suma entre 11
$dc1 = 11 - $dc1s % 11;

//Si vale 11 se le asigna 0, si vale 10 se le asigna 1
if ($dc1 == 11) $dc1 = 0;
if ($dc1 == 10) $dc1 = 1;

//Si no coincide con el DC 1 marca error
if ($dc1 != $ccc[8]) $error = 1;

//Suma los dígitos de la cuenta multiplicados por sus pesos
$dc2s = 0;
$dc2s += $ccc[10] * 1;
$dc2s += $ccc[11] * 2;
$dc2s += $ccc[12] * 4;
$dc2s += $ccc[13] * 8;
$dc2s += $ccc[14] * 5;
$dc2s += $ccc[15] * 10;
$dc2s += $ccc[16] * 9;
$dc2s += $ccc[17] * 7;
$dc2s += $ccc[18] * 3;
$dc2s += $ccc[19] * 6;

//El segundo DC es 11 menos el resto de la anteror suma entre 11
$dc2 = 11 - $dc2s % 11;

//Si vale 11 se le asigna 0, si vale 10 se le asigna 1
if ($dc2 == 11) $dc2 = 0;
if ($dc2 == 10) $dc2 = 1;

//Si no coincide con el DC 2 marca error
if ($dc2 != $ccc[9]) $error = 2;

 echo $dc1s.' - '.$dc2s.'<br>';

if ($error){
 //Error si alguna de las casillas está vacía
 echo '<b>ERROR:</b> Número de cuenta incorrecto.';
 
 exit;
}

 

 

Si juntamos la validación del DC de la CCC con la conversión a IBAN, podemos verificar y convertir las cuentas, aquí puede verse el código completo:


/**
 * @name Ejemplo de conversor de CCC a IBAN con validación de cuentas
 * @copyright (c)2015 Intervia IT
 * @link http://intervia.com/doc/convertir-cuentas-de-formato-ccc-a-iban/
 * @license MIT http://opensource.org/licenses/MIT
 */

//Inicializa el array para mensajes de error
$err = $msg = [];

//Inicializa el array para mensajes de error
$err = $msg = [];

/*
 * Inicializa las variables
 * p = switch para el envío
 * b = código de entidad
 * s = código de sucursal
 * d = dígito de control
 * c = número de cuenta
 * ccc = CCC entero
 */
$ini_vars = ['p','b','s','d','c','ccc'];
foreach ($ini_vars as $iv) {
    ${$iv} = preg_replace("/[^0-9]/i","",filter_input(
                    INPUT_GET, $iv, FILTER_SANITIZE_NUMBER_INT
            ));
    if (!isset(${$iv})) {
        ${$iv} = null;
    }
}


//Si no existe el número CCC completo lo concatena de b, s, d y c
if (!$ccc){
 $ccc = $b.$s.$d.$c;
}




/*
 * ******************
 * Validación del CCC
 * ******************
 */

//Inicializa la variable de error
$error = 0;

//Suma los dígitos del banco y la sucursal multiplicados por sus pesos
$dc1s = 0;
$dc1s += $ccc[0] * 4;
$dc1s += $ccc[1] * 8;
$dc1s += $ccc[2] * 5;
$dc1s += $ccc[3] * 10;
$dc1s += $ccc[4] * 9;
$dc1s += $ccc[5] * 7;
$dc1s += $ccc[6] * 3;
$dc1s += $ccc[7] * 6;

//El primer DC es 11 menos el resto de la anteror suma entre 11
$dc1 = 11 - $dc1s % 11;

//Si vale 11 se le asigna 0, si vale 10 se le asigna 1
if ($dc1 == 11) $dc1 = 0;
if ($dc1 == 10) $dc1 = 1;

//Si no coincide con el DC 1 marca error
if ($dc1 != $ccc[8]) $error = 1;

//Suma los dígitos de la cuenta multiplicados por sus pesos
$dc2s = 0;
$dc2s += $ccc[10] * 1;
$dc2s += $ccc[11] * 2;
$dc2s += $ccc[12] * 4;
$dc2s += $ccc[13] * 8;
$dc2s += $ccc[14] * 5;
$dc2s += $ccc[15] * 10;
$dc2s += $ccc[16] * 9;
$dc2s += $ccc[17] * 7;
$dc2s += $ccc[18] * 3;
$dc2s += $ccc[19] * 6;

//El segundo DC es 11 menos el resto de la anteror suma entre 11
$dc2 = 11 - $dc2s % 11;

//Si vale 11 se le asigna 0, si vale 10 se le asigna 1
if ($dc2 == 11) $dc2 = 0;
if ($dc2 == 10) $dc2 = 1;

//Si no coincide con el DC 2 marca error
if ($dc2 != $ccc[9]) $error = 2;

if ($error){
 //Error si alguna de las casillas está vacía
 $msg[] = '
 <b>ERROR:</b> Número de cuenta incorrecto.<br>
 No es posible calcular el IBAN con un CCC incorrecto.';
}





/*
 * ***************************************
 * Cálculo del IBAN si el CCC era correcto
 * ***************************************
 */

//Si se envió el formulario
if ($p ==1 && !$error){
 
 //Si falta alguno de los dígitos da error
 if(strlen($ccc) == 20){
 
 //Código de España para cálculo del DC del IBAN
 $es_iso = '142800';
 
 //Concatena el CCC con el código de país de España
 $bban_es = $ccc.$es_iso;

 /*
  * Hace la división del número de cuenta concatenado con el código de país entre 97
  * Obtiene el resto de esta división y lo resta de 98 para obtener el dígito de control
  * 
  * Se usa GMP "GNU Multiple Precision Arithmetic Library", para cálculos con 
  * precisión arbitraria (bignum), que permite operar con números de cualquier tamaño
  * mientras no se agote la memoria del sistema.
  * 
  * gmp_init genera el recurso a partir del número con la base indicada
  * gmp_mod calcula el resto de la división (modulo operation)
  * gmp_intval convierte un recurso GMP en un entero
  * 
  */
$ibandc = str_pad(98 - gmp_intval(gmp_mod(gmp_init($bban_es, 10),'97')),2,0,STR_PAD_LEFT);
 
 //Crea el código IBAN concatenando código de país, DC IBAN y cuenta
 $iban = 'ES'.$ibandc.$ccc;

 //Separa el iban en grupos de 4 para el formato impreso
 $ibani = substr($iban,0,4).' '.
 substr($iban,4,4).' '.
 substr($iban,8,4).' '.
 substr($iban,12,4).' '.
 substr($iban,16,4).' '.
 substr($iban,20,4).' '.
 substr($iban,24,4);

 //Muestra el resultado de la conversión
 $msg[] = '<h3>Código IBAN</h3>
 <b>Electrónico:</b> '.$iban.'<br>
 <b>Impreso:</b> '.$ibani;
 
 
 }else{
 //Error si alguna de las casillas está vacía
 $msg[] = '<b>ERROR:</b> Hay que introducir datos en todas las casillas 
 y sólo se admiten números. Si se pone el número entero, debe 
 tener 20 dígitos.';
 }
}




/*
 * *************************
 * Muestra mensajes de error
 * *************************
 */

if ($msg){
 echo '<div style="background-color:#eee;padding:3px;">';
 foreach ($msg as $m){
 echo $m;
 }
 echo '</div>';
}





/*
 * ************************************
 * Formulario para introducir la cuenta
 * ************************************
 */

?> 
<h3>Conversor de CCC a IBAN en PHP</h3>

<form method="GET" action="">
<input type="hidden" name="p" value="1">
<input type="text" placeholder="CCC entero" size="26" name="ccc" maxlength="23">
<input type="submit" value="Validar">
</form>

Código de ejemplo: 12341234161234567890<br><br><br>

<form method="GET" action="">
<input type="hidden" name="p" value="1">
<input type="text" placeholder="Banco" size="8" name="b" maxlength="4">/
<input type="text" placeholder="Oficina" size="8" name="s" maxlength="4">/
<input type="text" placeholder="DC" size="5" name="d" maxlength="2">/
<input type="text" placeholder="Cuenta" size="14" name="c" maxlength="10">/
<input type="submit" value="Validar">
</form>

Código de ejemplo: 1234 / 1234 / 16 / 1234567890<br><br><br>

 

 

Hay una demostración del funcionamiento de este código:
http://intervia.com/ccc2iban

 

 

 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *