Whiz Tools

Calculadora de l'Algorisme de Luhn

Calculadora de l'Algorisme de Luhn

Introducció

L'algorisme de Luhn, també conegut com a "mòdul 10" o "mod 10", és una fórmula de suma de control senzilla utilitzada per validar una varietat de números d'identificació, com ara números de targetes de crèdit, números d'assegurança social canadencs, números IMEI i números d'identificador de proveïdor nacional als Estats Units. Aquesta calculadora permet validar números mitjançant l'algorisme de Luhn i generar números vàlids que superen la comprovació de Luhn.

Com Funciona l'Algorisme de Luhn

L'algorisme de Luhn funciona de la següent manera:

  1. Començant pel dígit més a la dreta (excloent el dígit de control) i movent-se cap a l'esquerra, duplica el valor de cada segon dígit.
  2. Si el resultat d'aquesta operació de duplicació és superior a 9, resta 9 del resultat.
  3. Suma tots els dígits de la seqüència resultant.
  4. Si el total mòdul 10 és igual a 0 (si el total acaba en zero), llavors el número és vàlid segons la fórmula de Luhn; en cas contrari, no és vàlid.

Aquí teniu una representació visual de l'algorisme de Luhn:

1. Duplica cada segon dígit 2. Suma dígits (9 per a duplicats > 9) 3. Calcula la suma total 4. Comprova si suma % 10 == 0

Fórmula

L'algorisme de Luhn es pot expressar matemàticament de la següent manera:

Deixem que did_i sigui el ii-è dígit, comptant des del dígit més a la dreta (excloent el dígit de control) i movent-se cap a l'esquerra. Llavors el dígit de control d0d_0 es tria de manera 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

On mod\bmod és l'operació mòdul.

Casos d'Ús

L'algorisme de Luhn té diverses aplicacions en diferents camps:

  1. Validació de Targetes de Crèdit: La majoria dels números de targetes de crèdit es validen mitjançant l'algorisme de Luhn.
  2. Números d'Assegurança Social Canadencs: L'algorisme de Luhn s'utilitza per verificar la validesa d'aquests números d'identificació.
  3. Números IMEI: Els números IMEI dels telèfons mòbils incorporen un dígit de control validat per l'algorisme de Luhn.
  4. Números d'Identificador de Proveïdor Nacional (NPI): Utilitzats al sistema de salut dels Estats Units, aquests números es validen mitjançant l'algorisme de Luhn.
  5. ISBNs: Alguns números ISBN-10 utilitzen una variant de l'algorisme de Luhn per a la validació.

Alternatives

Si bé l'algorisme de Luhn és àmpliament utilitzat, hi ha altres algorismes de suma de control per a diferents propòsits:

  1. Algorisme de Damm: Un altre algorisme de dígit de control que detecta tots els errors d'un sol dígit i tots els errors de transposició adjacents.
  2. Algorisme de Verhoeff: Un algorisme de suma de control més complex que captura tots els errors d'un sol dígit i la majoria dels errors de transposició.
  3. Dígit de control ISBN-13: Utilitza un algorisme diferent que l'ISBN-10, que es basa en l'algorisme de Luhn.

Història

L'algorisme de Luhn va ser creat per Hans Peter Luhn, un científic informàtic d'IBM, el 1954. Luhn va ser un pioner en el camp de la ciència de la informació i se li atribueixen diverses innovacions, incloent el sistema d'indexació KWIC (Key Word In Context).

L'algorisme va ser dissenyat originalment per protegir contra errors accidentals, no contra atacs maliciosos. És important notar que, si bé l'algorisme de Luhn pot detectar molts errors comuns, no és una forma segura de xifrat i no s'ha de confiar per a propòsits de seguretat de dades.

Malgrat la seva antiguitat, l'algorisme de Luhn continua sent àmpliament utilitzat a causa de la seva simplicitat i efectivitat en la detecció d'errors comuns de transcripció.

Exemples d'Implementació

Aquí teniu alguns exemples de codi per implementar l'algorisme de Luhn en diversos llenguatges de programació:

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])))

## Exemple d'ús:
print(luhn_validate(4532015112830366))  # True
print(luhn_validate(4532015112830367))  # False
print(generate_valid_number(16))  # Genera un número vàlid de 16 dígits
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);
}

// Exemple d'ús:
console.log(luhnValidate(4532015112830366));  // true
console.log(luhnValidate(4532015112830367));  // false
console.log(generateValidNumber(16));  // Genera un número vàlid de 16 dígits
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àlid de 16 dígits
    }
}

Casos Límit i Consideracions Especials

Al implementar l'algorisme de Luhn, considereu els següents casos límit i consideracions especials:

  1. Validació d'Entrada: Assegureu-vos que l'entrada sigui una cadena de números vàlida. Els caràcters no numèrics haurien de ser gestionats adequadament (ja sigui eliminats o tractats com a entrada no vàlida).

  2. Zeros a l'Inici: L'algorisme hauria de funcionar correctament amb números que tinguin zeros a l'inici.

  3. Números Grans: Esteu preparats per gestionar números molt llargs que podrien excedir la capacitat dels tipus d'enters estàndard en alguns llenguatges de programació.

  4. Entrada Buida: Definiu com hauria de gestionar la vostra implementació cadenes buides o entrades nules.

  5. Conjunts de Caràcters No Estàndard: En algunes aplicacions, podríeu trobar números representats amb caràcters fora del rang estàndard 0-9. Definiu com s'haurien de gestionar.

  6. Consideracions de Rendiment: Per a aplicacions que necessiten validar un gran nombre d'entrades ràpidament, considereu optimitzar la implementació de l'algorisme.

Exemples Numèrics

  1. Número de Targeta de Crèdit Vàlid:

    • Número: 4532015112830366
    • Comprovació de Luhn: Vàlid
  2. Número de Targeta de Crèdit Invàlid:

    • Número: 4532015112830367
    • Comprovació de Luhn: Invàlid
  3. Número d'Assegurança Social Canadenc Vàlid:

    • Número: 046 454 286
    • Comprovació de Luhn: Vàlid
  4. Número IMEI Invàlid:

    • Número: 490154203237518
    • Comprovació de Luhn: Invàlid

Casos de Prova

Per verificar la implementació de l'algorisme de Luhn, podeu utilitzar els següents casos de prova:

def test_luhn_algorithm():
    assert luhn_validate(4532015112830366) == True
    assert luhn_validate(4532015112830367) == False
    assert luhn_validate(79927398713) == True
    assert luhn_validate(79927398714) == False
    
    # Prova de números generats
    for _ in range(10):
        assert luhn_validate(generate_valid_number(16)) == True
    
    print("Tots els tests han passat!")

test_luhn_algorithm()

Referències

  1. Luhn, H. P. (1960). "Computer for Verifying Numbers". US Patent 2,950,048.
  2. Gallian, Joseph. "The Mathematics of Identification Numbers." The College Mathematics Journal, vol. 22, no. 3, 1991, pp. 194–202. JSTOR, www.jstor.org/stable/2686878.
  3. "ISO/IEC 7812-1:2017". International Organization for Standardization. Retrieved August 2, 2024.
  4. Knuth, Donald. "The Art of Computer Programming, Volume 2: Seminumerical Algorithms". Addison-Wesley, 1997.
Feedback