Whiz Tools

Calculadora do Algoritmo de Luhn

Calculadora do Algoritmo de Luhn

Introdução

O algoritmo de Luhn, também conhecido como algoritmo de "módulo 10" ou "mod 10", é uma fórmula simples de verificação usada para validar uma variedade de números de identificação, como números de cartões de crédito, Números de Seguro Social do Canadá, números IMEI e números de Identificador Nacional de Provedor nos Estados Unidos. Esta calculadora permite que você valide números usando o algoritmo de Luhn e gere números válidos que passam na verificação de Luhn.

Como Funciona o Algoritmo de Luhn

O algoritmo de Luhn funciona da seguinte maneira:

  1. Começando pelo dígito mais à direita (excluindo o dígito de verificação) e movendo-se para a esquerda, dobre o valor de cada segundo dígito.
  2. Se o resultado dessa operação de duplicação for maior que 9, subtraia 9 do resultado.
  3. Some todos os dígitos na sequência resultante.
  4. Se o total módulo 10 for igual a 0 (se o total terminar em zero), então o número é válido de acordo com a fórmula de Luhn; caso contrário, não é válido.

Aqui está uma representação visual do algoritmo de Luhn:

1. Dobre cada segundo dígito 2. Some os dígitos (9 para dobrados > 9) 3. Calcule a soma total 4. Verifique se soma % 10 == 0

Fórmula

O algoritmo de Luhn pode ser expresso matematicamente da seguinte forma:

Seja did_i o ii-ésimo dígito, contando a partir do dígito mais à direita (excluindo o dígito de verificação) e movendo-se para a esquerda. Então o dígito de verificação d0d_0 é escolhido de forma 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

Onde mod\bmod é a operação de módulo.

Casos de Uso

O algoritmo de Luhn tem várias aplicações em diferentes campos:

  1. Validação de Cartão de Crédito: A maioria dos números de cartões de crédito é validada usando o algoritmo de Luhn.
  2. Números de Seguro Social do Canadá: O algoritmo de Luhn é usado para verificar a validade desses números de identificação.
  3. Números IMEI: Os números IMEI de telefones móveis incorporam um dígito de verificação validado pelo algoritmo de Luhn.
  4. Números de Identificador Nacional de Provedor (NPI): Usados no sistema de saúde dos Estados Unidos, esses números são validados usando o algoritmo de Luhn.
  5. ISBNs: Alguns números ISBN-10 usam uma variante do algoritmo de Luhn para validação.

Alternativas

Embora o algoritmo de Luhn seja amplamente utilizado, existem outros algoritmos de verificação para diferentes propósitos:

  1. Algoritmo de Damm: Outro algoritmo de dígito de verificação que detecta todos os erros de um dígito e todos os erros de transposição adjacentes.
  2. Algoritmo de Verhoeff: Um algoritmo de verificação mais complexo que captura todos os erros de um dígito e a maioria dos erros de transposição.
  3. Dígito de verificação ISBN-13: Usa um algoritmo diferente do ISBN-10, que é baseado no algoritmo de Luhn.

História

O algoritmo de Luhn foi criado por Hans Peter Luhn, um cientista da computação da IBM, em 1954. Luhn foi um pioneiro no campo da ciência da informação e é creditado com várias inovações, incluindo o sistema de indexação KWIC (Key Word In Context).

O algoritmo foi originalmente projetado para proteger contra erros acidentais, não ataques maliciosos. É importante notar que, embora o algoritmo de Luhn possa detectar muitos erros comuns, não é uma forma segura de criptografia e não deve ser confiado para fins de segurança de dados.

Apesar de sua idade, o algoritmo de Luhn continua amplamente utilizado devido à sua simplicidade e eficácia em capturar erros comuns de transcrição.

Exemplos de Implementação

Aqui estão alguns exemplos de código para implementar o algoritmo de Luhn em várias linguagens de programação:

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

## Exemplo de uso:
print(luhn_validate(4532015112830366))  # True
print(luhn_validate(4532015112830367))  # False
print(generate_valid_number(16))  # Gera um 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);
}

// Exemplo de uso:
console.log(luhnValidate(4532015112830366));  // true
console.log(luhnValidate(4532015112830367));  // false
console.log(generateValidNumber(16));  // Gera um 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));  // Gera um número válido de 16 dígitos
    }
}

Casos de Bordas e Considerações Especiais

Ao implementar o algoritmo de Luhn, considere os seguintes casos de borda e considerações especiais:

  1. Validação de Entrada: Certifique-se de que a entrada seja uma string numérica válida. Caracteres não numéricos devem ser tratados adequadamente (removidos ou considerados como entrada inválida).

  2. Zeros à Frente: O algoritmo deve funcionar corretamente com números que têm zeros à frente.

  3. Números Grandes: Esteja preparado para lidar com números muito longos que podem exceder a capacidade dos tipos de inteiros padrão em algumas linguagens de programação.

  4. Entrada Vazia: Defina como sua implementação deve lidar com strings vazias ou entradas nulas.

  5. Conjuntos de Caracteres Não Padrão: Em algumas aplicações, você pode encontrar números representados com caracteres fora do intervalo padrão de 0-9. Defina como esses devem ser tratados.

  6. Considerações de Desempenho: Para aplicações que precisam validar grandes quantidades de entradas rapidamente, considere otimizar a implementação do algoritmo.

Exemplos Numéricos

  1. Número Válido de Cartão de Crédito:

    • Número: 4532015112830366
    • Verificação de Luhn: Válido
  2. Número Inválido de Cartão de Crédito:

    • Número: 4532015112830367
    • Verificação de Luhn: Inválido
  3. Número Válido de Seguro Social Canadense:

    • Número: 046 454 286
    • Verificação de Luhn: Válido
  4. Número IMEI Inválido:

    • Número: 490154203237518
    • Verificação de Luhn: Inválido

Casos de Teste

Para verificar a implementação do algoritmo de Luhn, você pode usar os seguintes casos de teste:

def test_luhn_algorithm():
    assert luhn_validate(4532015112830366) == True
    assert luhn_validate(4532015112830367) == False
    assert luhn_validate(79927398713) == True
    assert luhn_validate(79927398714) == False
    
    # Teste números gerados
    for _ in range(10):
        assert luhn_validate(generate_valid_number(16)) == True
    
    print("Todos os testes passaram!")

test_luhn_algorithm()

Referências

  1. Luhn, H. P. (1960). "Computer for Verifying Numbers". Patente dos EUA 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". Organização Internacional de Normalização. Acessado em 2 de agosto de 2024.
  4. Knuth, Donald. "The Art of Computer Programming, Volume 2: Seminumerical Algorithms". Addison-Wesley, 1997.
Feedback