Waliduj i generuj numery za pomocą algorytmu Luhna, powszechnie stosowanego w numerach kart kredytowych, kanadyjskich numerach ubezpieczenia społecznego oraz innych numerach identyfikacyjnych. Sprawdź, czy numer przechodzi test Luhna, lub generuj ważne numery, które są zgodne z algorytmem.
Algorytm Luhna, znany również jako algorytm "moduł 10" lub "mod 10", to prosty wzór kontrolny używany do walidacji różnych numerów identyfikacyjnych, takich jak numery kart kredytowych, kanadyjskie numery ubezpieczenia społecznego, numery IMEI oraz numery identyfikacyjne dostawców w Stanach Zjednoczonych. Ten kalkulator pozwala na walidację numerów przy użyciu algorytmu Luhna oraz generowanie prawidłowych numerów, które przechodzą kontrolę Luhna.
Algorytm Luhna działa w następujący sposób:
Oto wizualna reprezentacja algorytmu Luhna:
Algorytm Luhna można wyrazić matematycznie w następujący sposób:
Niech będzie -tą cyfrą, licząc od najbardziej prawej cyfry (z wyjątkiem cyfry kontrolnej) i przesuwając się w lewo. Następnie cyfra kontrolna jest wybierana tak, aby:
Gdzie to operacja modulo.
Algorytm Luhna ma różne zastosowania w różnych dziedzinach:
Chociaż algorytm Luhna jest szeroko stosowany, istnieją inne algorytmy kontrolne do różnych celów:
Algorytm Luhna został stworzony przez Hansa Petera Luhna, naukowca z IBM, w 1954 roku. Luhn był pionierem w dziedzinie nauki o informacji i jest uznawany za twórcę kilku innowacji, w tym systemu indeksowania KWIC (Key Word In Context).
Algorytm został pierwotnie zaprojektowany w celu ochrony przed przypadkowymi błędami, a nie atakami złośliwymi. Ważne jest, aby zauważyć, że chociaż algorytm Luhna może wykryć wiele powszechnych błędów, nie jest bezpieczną formą szyfrowania i nie powinien być wykorzystywany do celów bezpieczeństwa danych.
Pomimo swojego wieku, algorytm Luhna pozostaje szeroko stosowany ze względu na swoją prostotę i skuteczność w wychwytywaniu powszechnych błędów transkrypcyjnych.
Oto kilka przykładów kodu implementującego algorytm Luhna w różnych językach programowania:
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## Przykład użycia:
22print(luhn_validate(4532015112830366)) # True
23print(luhn_validate(4532015112830367)) # False
24print(generate_valid_number(16)) # Generuje prawidłowy 16-cyfrowy numer
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// Przykład użycia:
29console.log(luhnValidate(4532015112830366)); // true
30console.log(luhnValidate(4532015112830367)); // false
31console.log(generateValidNumber(16)); // Generuje prawidłowy 16-cyfrowy numer
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 prawidłowy 16-cyfrowy numer
47 }
48}
49
Podczas implementacji algorytmu Luhna, należy wziąć pod uwagę następujące przypadki brzegowe i specjalne uwagi:
Walidacja wejścia: Upewnij się, że wejście jest prawidłowym ciągiem numerycznym. Niekontrolowane znaki powinny być odpowiednio obsługiwane (usunięte lub traktowane jako nieprawidłowe wejście).
Zera wiodące: Algorytm powinien działać poprawnie z numerami, które mają zera wiodące.
Duże liczby: Bądź przygotowany na obsługę bardzo długich numerów, które mogą przekraczać pojemność standardowych typów całkowitych w niektórych językach programowania.
Puste wejście: Zdefiniuj, jak twoja implementacja powinna obsługiwać puste ciągi lub wartości null.
Niekontrolowane zestawy znaków: W niektórych aplikacjach możesz napotkać numery reprezentowane znakami spoza standardowego zakresu 0-9. Zdefiniuj, jak powinny być one obsługiwane.
Rozważania dotyczące wydajności: Dla aplikacji, które muszą szybko walidować dużą liczbę wejść, rozważ optymalizację implementacji algorytmu.
Ważny numer karty kredytowej:
Nieprawidłowy numer karty kredytowej:
Ważny kanadyjski numer ubezpieczenia społecznego:
Nieprawidłowy numer IMEI:
Aby zweryfikować implementację algorytmu Luhna, możesz użyć następujących przypadków testowych:
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 # Testowanie wygenerowanych numerów
8 for _ in range(10):
9 assert luhn_validate(generate_valid_number(16)) == True
10
11 print("Wszystkie testy przeszły pomyślnie!")
12
13test_luhn_algorithm()
14