Whiz Tools

Calculadora del Algoritmo de Luhn

Calculadora del Algoritmo de Luhn

Introducción

El algoritmo de Luhn, también conocido como el algoritmo de "módulo 10" o "mod 10", es una fórmula de verificación simple utilizada para validar una variedad de números de identificación, como números de tarjetas de crédito, números de Seguro Social en Canadá, números IMEI y números de Identificador de Proveedor Nacional en los Estados Unidos. Esta calculadora te permite validar números utilizando el algoritmo de Luhn y generar números válidos que pasen la verificación de Luhn.

Cómo Funciona el Algoritmo de Luhn

El algoritmo de Luhn funciona de la siguiente manera:

  1. Comenzando desde el dígito más a la derecha (excluyendo el dígito de verificación) y moviéndose hacia la izquierda, duplica el valor de cada segundo dígito.
  2. Si el resultado de esta operación de duplicación es mayor que 9, resta 9 del resultado.
  3. Suma todos los dígitos en la secuencia resultante.
  4. Si el total módulo 10 es igual a 0 (si el total termina en cero), entonces el número es válido según la fórmula de Luhn; de lo contrario, no es válido.

Aquí hay una representación visual del algoritmo de Luhn:

1. Duplica cada segundo dígito 2. Suma los dígitos (9 para duplicados > 9) 3. Calcula la suma total 4. Verifica si suma % 10 == 0

Fórmula

El algoritmo de Luhn se puede expresar matemáticamente de la siguiente manera:

Sea did_i el ii-ésimo dígito, contando desde el dígito más a la derecha (excluyendo el dígito de verificación) y moviéndose hacia la izquierda. Entonces el dígito de verificación d0d_0 se elige de modo que:

(2d2nmod9+d2n1+2d2n2mod9+d2n3++2d2mod9+d1+d0)mod10=0(2d_{2n} \bmod 9 + d_{2n-1} + 2d_{2n-2} \bmod 9 + d_{2n-3} + \cdots + 2d_2 \bmod 9 + d_1 + d_0) \bmod 10 = 0

Donde mod\bmod es la operación de módulo.

Casos de Uso

El algoritmo de Luhn tiene varias aplicaciones en diferentes campos:

  1. Validación de Tarjetas de Crédito: La mayoría de los números de tarjetas de crédito se validan utilizando el algoritmo de Luhn.
  2. Números de Seguro Social en Canadá: El algoritmo de Luhn se utiliza para verificar la validez de estos números de identificación.
  3. Números IMEI: Los números IMEI de teléfonos móviles incorporan un dígito de verificación validado por el algoritmo de Luhn.
  4. Números de Identificador de Proveedor Nacional (NPI): Utilizados en el sistema de salud de los Estados Unidos, estos números se validan utilizando el algoritmo de Luhn.
  5. ISBNs: Algunos números ISBN-10 utilizan una variante del algoritmo de Luhn para la validación.

Alternativas

Si bien el algoritmo de Luhn es ampliamente utilizado, existen otros algoritmos de verificación para diferentes propósitos:

  1. Algoritmo de Damm: Otro algoritmo de dígito de verificación que detecta todos los errores de un solo dígito y todos los errores de transposición adyacente.
  2. Algoritmo de Verhoeff: Un algoritmo de verificación más complejo que captura todos los errores de un solo dígito y la mayoría de los errores de transposición.
  3. Dígito de verificación ISBN-13: Utiliza un algoritmo diferente al de ISBN-10, que se basa en el algoritmo de Luhn.

Historia

El algoritmo de Luhn fue creado por Hans Peter Luhn, un científico informático de IBM, en 1954. Luhn fue un pionero en el campo de la ciencia de la información y se le atribuyen varias innovaciones, incluido el sistema de indexación KWIC (Palabra Clave en Contexto).

El algoritmo fue diseñado originalmente para proteger contra errores accidentales, no ataques maliciosos. Es importante tener en cuenta que, aunque el algoritmo de Luhn puede detectar muchos errores comunes, no es una forma segura de cifrado y no debe confiarse en él para fines de seguridad de datos.

A pesar de su antigüedad, el algoritmo de Luhn sigue siendo ampliamente utilizado debido a su simplicidad y efectividad para detectar errores comunes de transcripción.

Ejemplos de Implementación

Aquí hay algunos ejemplos de código para implementar el algoritmo de Luhn en varios lenguajes de programación:

import random

def luhn_validate(number):
    digits = [int(d) for d in str(number)]
    checksum = 0
    for i in range(len(digits) - 1, -1, -1):
        d = digits[i]
        if (len(digits) - i) % 2 == 0:
            d = d * 2
            if d > 9:
                d -= 9
        checksum += d
    return checksum % 10 == 0

def generate_valid_number(length):
    digits = [random.randint(0, 9) for _ in range(length - 1)]
    checksum = sum(digits[::2]) + sum(sum(divmod(d * 2, 10)) for d in digits[-2::-2])
    check_digit = (10 - (checksum % 10)) % 10
    return int(''.join(map(str, digits + [check_digit])))

## Ejemplo de uso:
print(luhn_validate(4532015112830366))  # True
print(luhn_validate(4532015112830367))  # False
print(generate_valid_number(16))  # Genera un número válido de 16 dígitos
function luhnValidate(number) {
    const digits = number.toString().split('').map(Number);
    let checksum = 0;
    for (let i = digits.length - 1; i >= 0; i--) {
        let d = digits[i];
        if ((digits.length - i) % 2 === 0) {
            d *= 2;
            if (d > 9) d -= 9;
        }
        checksum += d;
    }
    return checksum % 10 === 0;
}

function generateValidNumber(length) {
    const digits = Array.from({length: length - 1}, () => Math.floor(Math.random() * 10));
    const checksum = digits.reduce((sum, digit, index) => {
        if ((length - 1 - index) % 2 === 0) {
            digit *= 2;
            if (digit > 9) digit -= 9;
        }
        return sum + digit;
    }, 0);
    const checkDigit = (10 - (checksum % 10)) % 10;
    return parseInt(digits.join('') + checkDigit);
}

// Ejemplo de uso:
console.log(luhnValidate(4532015112830366));  // true
console.log(luhnValidate(4532015112830367));  // false
console.log(generateValidNumber(16));  // Genera un número válido de 16 dígitos
import java.util.Random;

public class LuhnValidator {
    public static boolean luhnValidate(long number) {
        String digits = String.valueOf(number);
        int checksum = 0;
        boolean isEven = true;
        for (int i = digits.length() - 1; i >= 0; i--) {
            int digit = Character.getNumericValue(digits.charAt(i));
            if (isEven) {
                digit *= 2;
                if (digit > 9) digit -= 9;
            }
            checksum += digit;
            isEven = !isEven;
        }
        return checksum % 10 == 0;
    }

    public static long generateValidNumber(int length) {
        Random random = new Random();
        long[] digits = new long[length - 1];
        for (int i = 0; i < length - 1; i++) {
            digits[i] = random.nextInt(10);
        }
        long checksum = 0;
        for (int i = digits.length - 1; i >= 0; i--) {
            long digit = digits[i];
            if ((length - 1 - i) % 2 == 0) {
                digit *= 2;
                if (digit > 9) digit -= 9;
            }
            checksum += digit;
        }
        long checkDigit = (10 - (checksum % 10)) % 10;
        long result = 0;
        for (long digit : digits) {
            result = result * 10 + digit;
        }
        return result * 10 + checkDigit;
    }

    public static void main(String[] args) {
        System.out.println(luhnValidate(4532015112830366L));  // true
        System.out.println(luhnValidate(4532015112830367L));  // false
        System.out.println(generateValidNumber(16));  // Genera un número válido de 16 dígitos
    }
}

Casos Límite y Consideraciones Especiales

Al implementar el algoritmo de Luhn, considera los siguientes casos límite y consideraciones especiales:

  1. Validación de Entrada: Asegúrate de que la entrada sea una cadena de números válida. Los caracteres no numéricos deben manejarse adecuadamente (ya sea eliminados o tratados como entrada no válida).

  2. Ceros a la Izquierda: El algoritmo debe funcionar correctamente con números que tengan ceros a la izquierda.

  3. Números Grandes: Prepárate para manejar números muy largos que podrían exceder la capacidad de los tipos de enteros estándar en algunos lenguajes de programación.

  4. Entrada Vacía: Define cómo debe manejar tu implementación las cadenas vacías o las entradas nulas.

  5. Conjuntos de Caracteres No Estándar: En algunas aplicaciones, podrías encontrar números representados con caracteres fuera del rango estándar 0-9. Define cómo deben manejarse.

  6. Consideraciones de Rendimiento: Para aplicaciones que necesitan validar grandes cantidades de entradas rápidamente, considera optimizar la implementación del algoritmo.

Ejemplos Numéricos

  1. Número de Tarjeta de Crédito Válido:

    • Número: 4532015112830366
    • Verificación de Luhn: Válido
  2. Número de Tarjeta de Crédito Inválido:

    • Número: 4532015112830367
    • Verificación de Luhn: Inválido
  3. Número de Seguro Social Canadiense Válido:

    • Número: 046 454 286
    • Verificación de Luhn: Válido
  4. Número IMEI Inválido:

    • Número: 490154203237518
    • Verificación de Luhn: Inválido

Casos de Prueba

Para verificar la implementación del algoritmo de Luhn, puedes usar los siguientes casos de prueba:

def test_luhn_algorithm():
    assert luhn_validate(4532015112830366) == True
    assert luhn_validate(4532015112830367) == False
    assert luhn_validate(79927398713) == True
    assert luhn_validate(79927398714) == False
    
    # Probar números generados
    for _ in range(10):
        assert luhn_validate(generate_valid_number(16)) == True
    
    print("¡Todas las pruebas pasaron!")

test_luhn_algorithm()

Referencias

  1. Luhn, H. P. (1960). "Computadora para Verificar Números". Patente de EE. UU. 2,950,048.
  2. Gallian, Joseph. "Las Matemáticas de los Números de Identificación." The College Mathematics Journal, vol. 22, no. 3, 1991, pp. 194–202. JSTOR, www.jstor.org/stable/2686878.
  3. "ISO/IEC 7812-1:2017". Organización Internacional de Normalización. Recuperado el 2 de agosto de 2024.
  4. Knuth, Donald. "El Arte de Programar Computadoras, Volumen 2: Algoritmos Seminumerales". Addison-Wesley, 1997.
Feedback