Validujte a generujte čísla pomocou Luhnovho algoritmu, ktorý sa bežne používa pre čísla kreditných kariet, kanadské čísla sociálneho zabezpečenia a iné identifikačné čísla. Otestujte, či číslo prechádza Luhnovou kontrolou, alebo generujte platné čísla, ktoré spĺňajú algoritmus.
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.
Luhnov algoritmus funguje nasledovne:
Tu je vizuálna reprezentácia Luhnovho algoritmu:
Luhnov algoritmus môže byť matematicky vyjadrený nasledovne:
Nech je -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 vybraná tak, aby:
Kde je modulo operácia.
Luhnov algoritmus má rôzne aplikácie v rôznych oblastiach:
Hoci je Luhnov algoritmus široko používaný, existujú aj iné algoritmy kontrolného súčtu na rôzne účely:
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.
Tu sú niektoré príklady kódu na implementáciu Luhnovho algoritmu v rôznych programovacích jazykoch:
1import random
2
3def luhn_validate(number):
4 digits = [int(d) for d in str(number)]
5 checksum = 0
6 for i in range(len(digits) - 1, -1, -1):
7 d = digits[i]
8 if (len(digits) - i) % 2 == 0:
9 d = d * 2
10 if d > 9:
11 d -= 9
12 checksum += d
13 return checksum % 10 == 0
14
15def generate_valid_number(length):
16 digits = [random.randint(0, 9) for _ in range(length - 1)]
17 checksum = sum(digits[::2]) + sum(sum(divmod(d * 2, 10)) for d in digits[-2::-2])
18 check_digit = (10 - (checksum % 10)) % 10
19 return int(''.join(map(str, digits + [check_digit])))
20
21## Príklad použitia:
22print(luhn_validate(4532015112830366)) # True
23print(luhn_validate(4532015112830367)) # False
24print(generate_valid_number(16)) # Generuje platné 16-ciferné číslo
25
1function luhnValidate(number) {
2 const digits = number.toString().split('').map(Number);
3 let checksum = 0;
4 for (let i = digits.length - 1; i >= 0; i--) {
5 let d = digits[i];
6 if ((digits.length - i) % 2 === 0) {
7 d *= 2;
8 if (d > 9) d -= 9;
9 }
10 checksum += d;
11 }
12 return checksum % 10 === 0;
13}
14
15function generateValidNumber(length) {
16 const digits = Array.from({length: length - 1}, () => Math.floor(Math.random() * 10));
17 const checksum = digits.reduce((sum, digit, index) => {
18 if ((length - 1 - index) % 2 === 0) {
19 digit *= 2;
20 if (digit > 9) digit -= 9;
21 }
22 return sum + digit;
23 }, 0);
24 const checkDigit = (10 - (checksum % 10)) % 10;
25 return parseInt(digits.join('') + checkDigit);
26}
27
28// Príklad použitia:
29console.log(luhnValidate(4532015112830366)); // true
30console.log(luhnValidate(4532015112830367)); // false
31console.log(generateValidNumber(16)); // Generuje platné 16-ciferné číslo
32
1import java.util.Random;
2
3public class LuhnValidator {
4 public static boolean luhnValidate(long number) {
5 String digits = String.valueOf(number);
6 int checksum = 0;
7 boolean isEven = true;
8 for (int i = digits.length() - 1; i >= 0; i--) {
9 int digit = Character.getNumericValue(digits.charAt(i));
10 if (isEven) {
11 digit *= 2;
12 if (digit > 9) digit -= 9;
13 }
14 checksum += digit;
15 isEven = !isEven;
16 }
17 return checksum % 10 == 0;
18 }
19
20 public static long generateValidNumber(int length) {
21 Random random = new Random();
22 long[] digits = new long[length - 1];
23 for (int i = 0; i < length - 1; i++) {
24 digits[i] = random.nextInt(10);
25 }
26 long checksum = 0;
27 for (int i = digits.length - 1; i >= 0; i--) {
28 long digit = digits[i];
29 if ((length - 1 - i) % 2 == 0) {
30 digit *= 2;
31 if (digit > 9) digit -= 9;
32 }
33 checksum += digit;
34 }
35 long checkDigit = (10 - (checksum % 10)) % 10;
36 long result = 0;
37 for (long digit : digits) {
38 result = result * 10 + digit;
39 }
40 return result * 10 + checkDigit;
41 }
42
43 public static void main(String[] args) {
44 System.out.println(luhnValidate(4532015112830366L)); // true
45 System.out.println(luhnValidate(4532015112830367L)); // false
46 System.out.println(generateValidNumber(16)); // Generuje platné 16-ciferné číslo
47 }
48}
49
Pri implementácii Luhnovho algoritmu zvážte nasledujúce okrajové prípady a špeciálne úvahy:
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).
Vedúce nuly: Algoritmus by mal správne fungovať s číslami, ktoré majú vedúce nuly.
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.
Prázdny vstup: Definujte, ako by mala vaša implementácia spracovať prázdne reťazce alebo null vstupy.
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ť.
Úvahy o výkonnosti: Pre aplikácie, ktoré potrebujú rýchlo validovať veľké množstvo vstupov, zvážte optimalizáciu implementácie algoritmu.
Platné číslo kreditnej karty:
Neplatné číslo kreditnej karty:
Platné kanadské číslo sociálneho zabezpečenia:
Neplatné IMEI číslo:
Na overenie implementácie Luhnovho algoritmu môžete použiť nasledujúce testovacie prípady:
1def test_luhn_algorithm():
2 assert luhn_validate(4532015112830366) == True
3 assert luhn_validate(4532015112830367) == False
4 assert luhn_validate(79927398713) == True
5 assert luhn_validate(79927398714) == False
6
7 # Test generovaných čísel
8 for _ in range(10):
9 assert luhn_validate(generate_valid_number(16)) == True
10
11 print("Všetky testy prešli!")
12
13test_luhn_algorithm()
14