Whiz Tools

Kalkulator Luhn algoritma

Luhn algoritam kalkulator

Uvod

Luhn algoritam, poznat i kao "modulus 10" ili "mod 10" algoritam, je jednostavna formula za kontrolni zbir koja se koristi za validaciju različitih identifikacionih brojeva, kao što su brojevi kreditnih kartica, kanadski brojevi socijalnog osiguranja, IMEI brojevi i brojevi nacionalnog pružatelja identiteta u Sjedinjenim Američkim Državama. Ovaj kalkulator vam omogućava da validirate brojeve koristeći Luhn algoritam i generišete validne brojeve koji prolaze Luhn proveru.

Kako Luhn algoritam funkcioniše

Luhn algoritam funkcioniše na sledeći način:

  1. Počevši od desnog najudaljenijeg broja (izuzev kontrolnog broja) i krećući se levo, duplirajte vrednost svakog drugog broja.
  2. Ako je rezultat ove operacije dupliranja veći od 9, oduzmite 9 od rezultata.
  3. Saberite sve cifre u dobijenom nizu.
  4. Ako je ukupni zbir modulo 10 jednak 0 (ako ukupni zbir završava sa nulom), tada je broj validan prema Luhn formuli; u suprotnom, nije validan.

Evo vizuelne reprezentacije Luhn algoritma:

1. Duplirajte svaki drugi broj 2. Saberite cifre (9 za duplirane > 9) 3. Izračunajte ukupni zbir 4. Proverite da li zbir % 10 == 0

Formula

Luhn algoritam može se matematički izraziti na sledeći način:

Neka did_i bude ii-ta cifra, brojeći od desnog najudaljenijeg broja (izuzev kontrolnog broja) i krećući se levo. Tada se kontrolni broj d0d_0 bira tako da:

(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

Gde mod\bmod predstavlja modulo operaciju.

Upotreba

Luhn algoritam ima razne primene u različitim oblastima:

  1. Validacija brojeva kreditnih kartica: Većina brojeva kreditnih kartica se validira koristeći Luhn algoritam.
  2. Kanadski brojevi socijalnog osiguranja: Luhn algoritam se koristi za verifikaciju validnosti ovih identifikacionih brojeva.
  3. IMEI brojevi: Brojevi mobilnih telefona IMEI uključuju kontrolni broj koji se validira Luhn algoritmom.
  4. Nacionalni identifikator pružatelja (NPI) brojevi: Koriste se u zdravstvenom sistemu Sjedinjenih Američkih Država, ovi brojevi se validiraju koristeći Luhn algoritam.
  5. ISBN: Neki ISBN-10 brojevi koriste varijantu Luhn algoritma za validaciju.

Alternative

Iako je Luhn algoritam široko korišćen, postoje i drugi algoritmi za kontrolni zbir za različite svrhe:

  1. Damm algoritam: Još jedan algoritam za kontrolni broj koji otkriva sve greške sa jednim ciframa i sve greške u susednim transpozicijama.
  2. Verhoeff algoritam: Složeniji algoritam za kontrolni zbir koji hvata sve greške sa jednim ciframa i većinu grešaka u transpoziciji.
  3. ISBN-13 kontrolni broj: Koristi drugačiji algoritam od ISBN-10, koji se zasniva na Luhn algoritmu.

Istorija

Luhn algoritam je stvorio Hans Peter Luhn, IBM-ov informatičar, 1954. godine. Luhn je bio pionir u oblasti informacione nauke i zaslužan je za nekoliko inovacija, uključujući KWIC (Key Word In Context) indeksni sistem.

Algoritam je prvobitno dizajniran da zaštiti od slučajnih grešaka, a ne od zlonamernih napada. Važno je napomenuti da, iako Luhn algoritam može otkriti mnoge uobičajene greške, to nije siguran oblik enkripcije i ne bi se trebao oslanjati na njega za svrhe bezbednosti podataka.

Uprkos svom uzrastu, Luhn algoritam ostaje široko korišćen zbog svoje jednostavnosti i efikasnosti u hvatanju uobičajenih grešaka prilikom prepisivanja.

Primeri implementacije

Evo nekoliko primera koda za implementaciju Luhn algoritma na različitim programskim jezicima:

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

## Primer korišćenja:
print(luhn_validate(4532015112830366))  # True
print(luhn_validate(4532015112830367))  # False
print(generate_valid_number(16))  # Generiše validan 16-cifren broj
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);
}

// Primer korišćenja:
console.log(luhnValidate(4532015112830366));  // true
console.log(luhnValidate(4532015112830367));  // false
console.log(generateValidNumber(16));  // Generiše validan 16-cifren broj
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));  // Generiše validan 16-cifren broj
    }
}

Ivicne situacije i posebna razmatranja

Kada implementirate Luhn algoritam, razmotrite sledeće ivicne situacije i posebna razmatranja:

  1. Validacija ulaza: Osigurajte da je ulaz validan broj string. Ne-digitalni karakteri treba da budu pravilno obrađeni (ili uklonjeni ili tretirani kao nevalidan ulaz).

  2. Vodeće nule: Algoritam bi trebao ispravno raditi sa brojevima koji imaju vodeće nule.

  3. Veliki brojevi: Budite spremni da obradite vrlo duge brojeve koji mogu premašiti kapacitet standardnih celih tipova u nekim programskim jezicima.

  4. Prazan ulaz: Definišite kako vaša implementacija treba da se nosi sa praznim stringovima ili null ulazima.

  5. Ne-standardni skupovi karaktera: U nekim aplikacijama možete naići na brojeve predstavljene karakterima van standardnog opsega 0-9. Definišite kako bi se ovakvi trebali obraditi.

  6. Razmatranja performansi: Za aplikacije koje trebaju brzo da validiraju veliki broj ulaza, razmotrite optimizaciju implementacije algoritma.

Numerički primeri

  1. Validan broj kreditne kartice:

    • Broj: 4532015112830366
    • Luhn provera: Validan
  2. Nevalidan broj kreditne kartice:

    • Broj: 4532015112830367
    • Luhn provera: Nevalidan
  3. Validan kanadski broj socijalnog osiguranja:

    • Broj: 046 454 286
    • Luhn provera: Validan
  4. Nevalidan IMEI broj:

    • Broj: 490154203237518
    • Luhn provera: Nevalidan

Test slučajevi

Da biste verifikovali implementaciju Luhn algoritma, možete koristiti sledeće test slučajeve:

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 generisanih brojeva
    for _ in range(10):
        assert luhn_validate(generate_valid_number(16)) == True
    
    print("Svi testovi su prošli!")

test_luhn_algorithm()

Reference

  1. Luhn, H. P. (1960). "Računar za verifikaciju brojeva". US Patent 2,950,048.
  2. Gallian, Joseph. "Matematika identifikacionih brojeva." The College Mathematics Journal, vol. 22, no. 3, 1991, str. 194–202. JSTOR, www.jstor.org/stable/2686878.
  3. "ISO/IEC 7812-1:2017". Međunarodna organizacija za standardizaciju. Preuzeto 2. avgusta 2024.
  4. Knuth, Donald. "Umjetnost programiranja računara, Tom 2: Polunumerički algoritmi". Addison-Wesley, 1997.
Feedback