Whiz Tools

Kalkulačka Luhnovho algoritmu

Kalkulátor Luhnovho algoritmu

Úvod

Luhnov algoritmus, známy aj ako "modulus 10" alebo "mod 10" algoritmus, je jednoduchý kontrolný súčet používaný na validáciu rôznych identifikačných čísel, ako sú čísla kreditných kariet, kanadské čísla sociálneho zabezpečenia, IMEI čísla a čísla národného poskytovateľa identifikátorov v Spojených štátoch. Tento kalkulátor vám umožňuje validovať čísla pomocou Luhnovho algoritmu a generovať platné čísla, ktoré prechádzajú Luhnovou kontrolou.

Ako funguje Luhnov algoritmus

Luhnov algoritmus funguje nasledovne:

  1. Začnite od pravého najviac čísla (s výnimkou kontrolného čísla) a pohybujte sa doľava, zdvojnásobte hodnotu každého druhého čísla.
  2. Ak je výsledok tejto operácie zdvojnásobenia väčší ako 9, odpočítajte 9 od výsledku.
  3. Sčítajte všetky číslice v výslednej sekvencii.
  4. Ak je celkový súčet modulo 10 rovný 0 (ak celkový súčet končí nulou), potom je číslo platné podľa Luhnovej formulácie; inak nie je platné.

Tu je vizuálna reprezentácia Luhnovho algoritmu:

1. Zdvojnásobte každú druhú číslicu 2. Sčítajte číslice (9 pre zdvojené > 9) 3. Vypočítajte celkový súčet 4. Skontrolujte, či súčet % 10 == 0

Formula

Luhnov algoritmus môže byť matematicky vyjadrený nasledovne:

Nech did_i je ii-tá číslica, počítajúc od pravého najviac čísla (s výnimkou kontrolného čísla) a pohybujúc sa doľava. Potom je kontrolná číslica d0d_0 vybraná tak, aby:

(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

Kde mod\bmod je modulo operácia.

Použitie

Luhnov algoritmus má rôzne aplikácie v rôznych oblastiach:

  1. Validácia kreditných kariet: Väčšina čísel kreditných kariet je validovaná pomocou Luhnovho algoritmu.
  2. Kanadské čísla sociálneho zabezpečenia: Luhnov algoritmus sa používa na overenie platnosti týchto identifikačných čísel.
  3. IMEI čísla: Čísla IMEI mobilných telefónov obsahujú kontrolnú číslicu, ktorú validuje Luhnov algoritmus.
  4. Čísla národného poskytovateľa (NPI): Používané v americkom zdravotníckom systéme, tieto čísla sú validované pomocou Luhnovho algoritmu.
  5. ISBN: Niektoré čísla ISBN-10 používajú variant Luhnoveho algoritmu na validáciu.

Alternatívy

Hoci je Luhnov algoritmus široko používaný, existujú aj iné algoritmy kontrolného súčtu na rôzne účely:

  1. Dammov algoritmus: Ďalší algoritmus kontrolnej číslice, ktorý detekuje všetky jednociferné chyby a všetky susedné transpozičné chyby.
  2. Verhoeffov algoritmus: Zložitejší algoritmus kontrolného súčtu, ktorý zachytáva všetky jednociferné chyby a väčšinu transpozičných chýb.
  3. Kontrolná číslica ISBN-13: Používa iný algoritmus ako ISBN-10, ktorý je založený na Luhnovom algoritme.

História

Luhnov algoritmus vytvoril Hans Peter Luhn, počítačový vedec z IBM, v roku 1954. Luhn bol priekopníkom v oblasti informačnej vedy a je známy množstvom inovácií, vrátane systému indexovania KWIC (Kľúčové slová v kontexte).

Algoritmus bol pôvodne navrhnutý na ochranu proti náhodným chybám, nie na zlé útoky. Je dôležité poznamenať, že hoci Luhnov algoritmus dokáže detekovať mnohé bežné chyby, nie je to bezpečná forma šifrovania a nemal by sa spoliehať na účely zabezpečenia údajov.

Napriek svojmu veku zostáva Luhnov algoritmus široko používaný vďaka svojej jednoduchosti a účinnosti pri zachytávaní bežných prepisovacích chýb.

Implementačné príklady

Tu sú niektoré príklady kódu na implementáciu Luhnovho algoritmu v rôznych programovacích jazykoch:

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

## Príklad použitia:
print(luhn_validate(4532015112830366))  # True
print(luhn_validate(4532015112830367))  # False
print(generate_valid_number(16))  # Generuje platné 16-ciferné číslo
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);
}

// Príklad použitia:
console.log(luhnValidate(4532015112830366));  // true
console.log(luhnValidate(4532015112830367));  // false
console.log(generateValidNumber(16));  // Generuje platné 16-ciferné číslo
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));  // Generuje platné 16-ciferné číslo
    }
}

Okrajové prípady a špeciálne úvahy

Pri implementácii Luhnovho algoritmu zvážte nasledujúce okrajové prípady a špeciálne úvahy:

  1. Validácia vstupu: Uistite sa, že vstup je platný reťazec čísiel. Nečíselné znaky by mali byť spracované primerane (buď odstránené, alebo považované za neplatný vstup).

  2. Vedúce nuly: Algoritmus by mal správne fungovať s číslami, ktoré majú vedúce nuly.

  3. Veľké čísla: Buďte pripravení spracovať veľmi dlhé čísla, ktoré môžu presiahnuť kapacitu štandardných celočíselných typov v niektorých programovacích jazykoch.

  4. Prázdny vstup: Definujte, ako by mala vaša implementácia spracovať prázdne reťazce alebo null vstupy.

  5. Neštandardné znakové sady: V niektorých aplikáciách môžete naraziť na čísla reprezentované znakmi mimo štandardného rozsahu 0-9. Definujte, ako by sa s nimi malo zaobchádzať.

  6. Úvahy o výkonnosti: Pre aplikácie, ktoré potrebujú rýchlo validovať veľké množstvo vstupov, zvážte optimalizáciu implementácie algoritmu.

Číselné príklady

  1. Platné číslo kreditnej karty:

    • Číslo: 4532015112830366
    • Luhnova kontrola: Platné
  2. Neplatné číslo kreditnej karty:

    • Číslo: 4532015112830367
    • Luhnova kontrola: Neplatné
  3. Platné kanadské číslo sociálneho zabezpečenia:

    • Číslo: 046 454 286
    • Luhnova kontrola: Platné
  4. Neplatné IMEI číslo:

    • Číslo: 490154203237518
    • Luhnova kontrola: Neplatné

Testovacie prípady

Na overenie implementácie Luhnovho algoritmu môžete použiť nasledujúce testovacie prípady:

def test_luhn_algorithm():
    assert luhn_validate(4532015112830366) == True
    assert luhn_validate(4532015112830367) == False
    assert luhn_validate(79927398713) == True
    assert luhn_validate(79927398714) == False
    
    # Test generovaných čísel
    for _ in range(10):
        assert luhn_validate(generate_valid_number(16)) == True
    
    print("Všetky testy prešli!")

test_luhn_algorithm()

Odkazy

  1. Luhn, H. P. (1960). "Počítač na overovanie čísel". US Patent 2,950,048.
  2. Gallian, Joseph. "Matematika identifikačných čísel." The College Mathematics Journal, vol. 22, no. 3, 1991, pp. 194–202. JSTOR, www.jstor.org/stable/2686878.
  3. "ISO/IEC 7812-1:2017". Medzinárodná organizácia pre normalizáciu. Získané 2. augusta 2024.
  4. Knuth, Donald. "Umenie počítačového programovania, Zväzok 2: Seminumerické algoritmy". Addison-Wesley, 1997.
Feedback