Algoritmo de Luhn

Nombrada en honor a Leonardo de Pisa, conocido como Fibonacci, esta secuencia numérica desempeña un papel significativo en diversos campos, desde las ciencias hasta las artes.

El algoritmo de Luhn, también conocido como la fórmula de Luhn, es un método de suma de verificación utilizado ampliamente para validar una variedad de números de identificación, como números de tarjetas de crédito y números de identificación nacionales. En este artículo, exploraremos la historia del algoritmo de Luhn, cómo se implementa, los pasos para calcular el dígito verificador y su uso actual en la verificación de tarjetas de crédito.

El algoritmo de Luhn fue inventado por el científico alemán Hans Peter Luhn en 1954, mientras trabajaba en IBM. Luhn quería diseñar un algoritmo simple y eficaz para proteger los números de identificación contra errores tipográficos. Su algoritmo es ampliamente utilizado en la actualidad para validar números de tarjetas de crédito, así como en otros sistemas de identificación.

Algoritmo:
- Comenzando por el penúltimo dígito (el dígito a la izquierda del dígito verificador) y avanzando hacia la izquierda, duplicar cada segundo dígito.
- Si el resultado de duplicar un dígito es un número de dos dígitos, sumarlos para obtener un solo dígito (por ejemplo, si el resultado es 14, sumar como 1 + 4 = 5; o restarle 9).
- Sumar todos los dígitos no duplicados y los dígitos duplicados ajustados.
- Calcular el módulo 10 de la suma total; y restar 10 menos este número (y cambiando por 0 si es 0 el módulo 10 de la suma). Este es el dígito verificador.

Aplicaciones:
Actualmente se utiliza en las tarjetas de crédito de 16 dígitos para generar el dígito verificador, y asegurar que la captura fue correcta; previniendo errores al hacer transferencias electrónicas o cargos.

Código de ejemplo en Rust

pub fn is_valid_luhn(number_str: &str) -> bool {
    let digits: Vec = number_str
        .chars()
        .filter(|c| c.is_ascii_digit())
        .filter_map(|c| c.to_digit(10))
        .collect();

    if digits.len() < 2 {
        return false;
    }

    let mut sum = 0;
    let mut double_digit = false;

    for digit in digits.iter().rev() {
        let mut current_digit = *digit;

        if double_digit {
            current_digit *= 2;
            if current_digit > 9 {
                current_digit -= 9; // (e.j., 14 -> 1+4 = 5)
            }
        }
        sum += current_digit;
        double_digit = !double_digit;
    }

    sum % 10 == 0
}