METODOLOGÍA · ESTÁNDAR GLOBAL
IBAN: el algoritmo MOD-97 (ISO 13616)
El IBAN usa el algoritmo MOD-97 definido en ISO 13616 para detectar errores en números de cuenta bancaria internacionales. Esta página explica cada paso del algoritmo, trabaja un ejemplo con un IBAN alemán real, y enumera 13 edge cases de producción — incluyendo por qué BigInt es obligatorio en JavaScript.
El algoritmo
El IBAN (International Bank Account Number) sigue la norma ISO 13616. El algoritmo de verificación es MOD-97. Un IBAN tiene hasta 34 caracteres: código de país (2 letras) + dígitos de control (2 dígitos) + BBAN (hasta 30 alfanumérico).
Los pasos del algoritmo:
- Mover los 4 primeros caracteres al final de la cadena. Ej: DE89370400440532013000 → 370400440532013000DE89
- Reemplazar cada letra por su equivalente numérico: A=10, B=11, … Z=35.
- Calcular la cadena numérica resultante mod 97. Si el resultado es 1, el IBAN es válido.
Ejemplo numérico paso a paso
Verificamos el IBAN alemán DE89 3704 0044 0532 0130 00.
DE89370400440532013000370400440532013000DE89370400440532013000138989370400440532013000138989 mod 97 = 1 ✓Pseudocódigo
iban = strip_spaces(input).toUpperCase()
if length < 15 OR length > 34 → INVALID
if iban[0..1] not alpha OR iban[2..3] not digits → INVALID
rearranged = iban[4..] + iban[0..3]
numeric_str = replace each letter C with (ord(C) − ord('A') + 10)
return to_bigint(numeric_str) mod 97 == 1Edge cases que una implementación simple no maneja
- Longitud fija por país: cada país tiene una longitud IBAN fija definida en el registro ISO 13616-1. Alemania: 22, España: 24, UK: 22, Italia: 27, Francia: 27. Un IBAN que pasa MOD-97 pero no respeta la longitud de su país es inválido.
- Espacios cada 4 caracteres (formato imprimible): el formato legible por humanos incluye espacios (DE89 3704 0044 0532 0130 00). Deben eliminarse antes de validar. Strings con tabs o newlines mezclados también aparecen en imports de archivos.
- BigInt en JavaScript: el número resultante de la conversión puede tener 68 dígitos. Number.MAX_SAFE_INTEGER tiene 16 dígitos. Sin BigInt, mod 97 producirá resultados incorrectos para IBANs largos.
- Lowercase o mixed case: el estándar ISO define el IBAN en mayúsculas. Inputs en minúsculas (de89...) o mixed case deben normalizarse antes de validar. Algunos bancos los entregan en minúsculas en sus APIs.
- Código de país inválido: MOD-97 puede pasar para un string con un código de país que no existe en el registro IBAN. La verificación del country code contra la lista ISO 3166-1 alpha-2 es un paso adicional.
- BBAN structure varies por país: el BBAN tiene estructura interna (código de banco, sucursal, número de cuenta) que varía por país. MOD-97 pasa si los dígitos son correctos, pero el BBAN puede tener sub-estructura inválida.
- IBAN válido ≠ cuenta activa: MOD-97 verifica el checksum del formato, no que la cuenta exista, esté activa, o tenga fondos. Un IBAN con un dígito cambiado que sigue siendo MOD-97 válido puede apuntar a una cuenta de otra persona.
- Argentina no usa IBAN: Argentina usa CBU (22 dígitos) para transferencias domésticas. No hay código de país AR en el registro IBAN. Sistemas globales que asumen IBAN universal fallan con cuentas argentinas.
- Brasil y uso parcial de IBAN: Brasil usa IBAN solo en transferencias SWIFT internacionales, no en TED/PIX domésticos. Validar un CBU o chave PIX brasileña como IBAN es un error de diseño.
- Países con IBAN no estándar o territorios offshore: algunos territorios emiten IBANs que pasan MOD-97 pero no están en el registro oficial SWIFT. La lista de países válidos debe actualizarse periódicamente.
- Caracteres Unicode invisibles: copiar un IBAN de un PDF o de un email con caracteres de control (zero-width space, soft hyphen) puede hacer que el strip de espacios no elimine todos los separadores no numéricos.
- Performance del módulo sobre strings largos: calcular mod 97 sobre un BigInt de 68 dígitos en runtime puede ser un cuello de botella si se validan millones de IBANs. Chunking (calcular mod en grupos de dígitos) es más eficiente.
- IBAN como campo opcional vs obligatorio: en sistemas de pagos internacionales, algunos flujos aceptan IBAN o SWIFT+número de cuenta alternativamente. Validar como IBAN un campo que puede ser cualquiera de los dos produce falsos negativos.
¿Querés saltarte todo esto?
Manejar todos estos edge cases en producción cuesta semanas de testing y mantenimiento permanente conforme cambian las reglas regulatorias. La API de Normadata maneja todo lo de arriba — incluyendo los casos que ni listamos aquí — con una sola llamada REST.
Fuentes
ISO 13616-1:2020 — International Bank Account Number (IBAN). SWIFT/ECBS IBAN Registry. El estándar es público y de libre acceso.