Luhno algoritmo skaičiuoklė - numerių patvirtinimas ir generavimas
Patvirtinkite ir generuokite numerius naudodami Luhno algoritmą, dažnai naudojamą kreditinių kortelių numeriams, Kanados socialinio draudimo numeriams ir kitiems identifikavimo numeriams. Patikrinkite, ar numeris atitinka Luhno patikrinimą, arba generuokite galiojančius numerius, kurie atitinka algoritmą.
Luhno algoritmo skaičiuoklė
Dokumentacija
Luhn algoritmo skaičiuoklė
Įvadas
Luhn algoritmas, dar žinomas kaip "modulio 10" arba "mod 10" algoritmas, yra paprasta kontrolinė suma, naudojama įvairių identifikavimo numerių, tokių kaip kreditinių kortelių numeriai, Kanados socialinio draudimo numeriai, IMEI numeriai ir nacionaliniai teikėjų identifikavimo numeriai JAV, patvirtinimui. Ši skaičiuoklė leidžia jums patvirtinti numerius naudojant Luhn algoritmą ir generuoti galiojančius numerius, kurie praeina Luhn patikrinimą.
Kaip veikia Luhn algoritmas
Luhn algoritmas veikia taip:
- Pradedant nuo dešiniojo skaitmens (neįskaitant kontrolinio skaitmens) ir judant į kairę, padvigubinkite kiekvieno antro skaitmens reikšmę.
- Jei šio padvigubinimo rezultatas viršija 9, atimkite 9 iš rezultato.
- Sudėkite visus skaitmenis gautame sekoje.
- Jei bendras skaičius modulo 10 yra lygus 0 (jei bendras skaičius baigiasi nuliu), tuomet numeris yra galiojantis pagal Luhn formulę; priešingu atveju jis nėra galiojantis.
Štai vizualinė Luhn algoritmo atvaizdavimo schema:
Formulė
Luhn algoritmas gali būti išreikštas matematiškai taip:
Tegu yra -asis skaitmuo, skaičiuojant nuo dešiniojo skaitmens (neįskaitant kontrolinio skaitmens) ir judant į kairę. Tada kontrolinis skaitmuo pasirenkamas taip, kad:
Kur yra modulo operacija.
Naudojimo atvejai
Luhn algoritmas turi įvairių taikymo sričių skirtingose srityse:
- Kreditinių kortelių patvirtinimas: Dauguma kreditinių kortelių numerių yra patvirtinami naudojant Luhn algoritmą.
- Kanados socialinio draudimo numeriai: Luhn algoritmas naudojamas šių identifikavimo numerių galiojimui patvirtinti.
- IMEI numeriai: Mobiliojo telefono IMEI numeriai apima kontrolinį skaitmenį, kurį patvirtina Luhn algoritmas.
- Nacionaliniai teikėjų identifikavimo (NPI) numeriai: Naudojami JAV sveikatos priežiūros sistemoje, šie numeriai yra patvirtinami naudojant Luhn algoritmą.
- ISBN: Kai kurie ISBN-10 numeriai naudoja Luhn algoritmo variantą patvirtinimui.
Alternatyvos
Nors Luhn algoritmas yra plačiai naudojamas, yra ir kitų kontrolinių sumų algoritmų skirtingiems tikslams:
- Damm algoritmas: Kitas kontrolinio skaitmens algoritmas, kuris aptinka visus vieno skaitmens klaidas ir visas gretimas transpozicijas.
- Verhoeff algoritmas: Sudėtingesnis kontrolinio skaitmens algoritmas, kuris aptinka visas vieno skaitmens klaidas ir daugumą transpozicijų.
- ISBN-13 kontrolinis skaitmuo: Naudoja kitokį algoritmą nei ISBN-10, kuris remiasi Luhn algoritmu.
Istorija
Luhn algoritmą sukūrė Hans Peter Luhn, IBM kompiuterių mokslininkas, 1954 metais. Luhn buvo informacijos mokslo pionierius ir jam priskiriama daugybė inovacijų, įskaitant KWIC (Key Word In Context) indeksavimo sistemą.
Algoritmas iš pradžių buvo sukurtas apsaugoti nuo atsitiktinių klaidų, o ne nuo piktybinių atakų. Svarbu pažymėti, kad nors Luhn algoritmas gali aptikti daugelį įprastų klaidų, jis nėra saugi šifravimo forma ir neturėtų būti naudojamas duomenų saugumo tikslais.
Nepaisant savo amžiaus, Luhn algoritmas išlieka plačiai naudojamas dėl savo paprastumo ir efektyvumo, aptinkant įprastas rašymo klaidas.
Įgyvendinimo pavyzdžiai
Štai keletas kodo pavyzdžių, kaip įgyvendinti Luhn algoritmą įvairiose programavimo kalbose:
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## Pavyzdžio naudojimas:
22print(luhn_validate(4532015112830366)) # True
23print(luhn_validate(4532015112830367)) # False
24print(generate_valid_number(16)) # Generuoja galiojantį 16 skaitmenų 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// Pavyzdžio naudojimas:
29console.log(luhnValidate(4532015112830366)); // true
30console.log(luhnValidate(4532015112830367)); // false
31console.log(generateValidNumber(16)); // Generuoja galiojantį 16 skaitmenų 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)); // Generuoja galiojantį 16 skaitmenų numerį
47 }
48}
49
Kraštutiniai atvejai ir specialūs svarstymai
Įgyvendinant Luhn algoritmą, atsižvelkite į šiuos kraštutinius atvejus ir specialius svarstymus:
-
Įvesties patikrinimas: Užtikrinkite, kad įvestis būtų galiojantis numerio simbolių rinkinys. Ne skaitmeniniai simboliai turėtų būti tinkamai apdoroti (arba pašalinti, arba laikomi negaliojančia įvestimi).
-
Pirmieji nuliai: Algoritmas turėtų teisingai veikti su numeriais, turinčiais pirmuosius nulius.
-
Dideli numeriai: Būkite pasiruošę tvarkyti labai ilgus numerius, kurie gali viršyti standartinių sveikųjų skaičių tipų talpą kai kuriose programavimo kalbose.
-
Tuščia įvestis: Apibrėžkite, kaip jūsų įgyvendinimas turėtų tvarkyti tuščius simbolių rinkinius arba null įvestis.
-
Ne standartiniai simbolių rinkiniai: Kai kuriose programose galite susidurti su numeriais, kurie yra atvaizduojami simboliais už standartinio 0-9 intervalo. Apibrėžkite, kaip šie turėtų būti tvarkomi.
-
Veiklos svarstymai: Programoms, kurioms reikia greitai patvirtinti didelį skaičių įvesties, apsvarstykite algoritmo įgyvendinimo optimizavimą.
Skaitmeniniai pavyzdžiai
-
Galiojantis kreditinės kortelės numeris:
- Numeris: 4532015112830366
- Luhn patikrinimas: Galiojantis
-
Negaliojantis kreditinės kortelės numeris:
- Numeris: 4532015112830367
- Luhn patikrinimas: Negaliojantis
-
Galiojantis Kanados socialinio draudimo numeris:
- Numeris: 046 454 286
- Luhn patikrinimas: Galiojantis
-
Negaliojantis IMEI numeris:
- Numeris: 490154203237518
- Luhn patikrinimas: Negaliojantis
Testavimo atvejai
Norėdami patvirtinti Luhn algoritmo įgyvendinimą, galite naudoti šiuos testavimo atvejus:
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 # Testuokite generuotus numerius
8 for _ in range(10):
9 assert luhn_validate(generate_valid_number(16)) == True
10
11 print("Visi testai praėjo!")
12
13test_luhn_algorithm()
14
Nuorodos
- Luhn, H. P. (1960). "Kompiuteris, patvirtinantis numerius". JAV patentas 2,950,048.
- Gallian, Joseph. "Identifikavimo numerių matematika." Koleginė matematikos žurnalas, t. 22, nr. 3, 1991, p. 194–202. JSTOR, www.jstor.org/stable/2686878.
- "ISO/IEC 7812-1:2017". Tarptautinė standartizacijos organizacija. Gauta 2024 m. rugpjūčio 2 d.
- Knuth, Donald. "Kompiuterinės programavimo meno menas, 2 tomas: Seminumeriniai algoritmai". Addison-Wesley, 1997.
Atsiliepimai
Spustelėkite atsiliepimo skanėlį, norėdami pradėti teikti atsiliepimus apie šį įrankį