Xác thực và tạo số bằng cách sử dụng thuật toán Luhn, thường được sử dụng cho số thẻ tín dụng, Số An Sinh Xã Hội Canada và các số nhận dạng khác. Kiểm tra xem một số có vượt qua kiểm tra Luhn hay không hoặc tạo ra các số hợp lệ tuân thủ thuật toán.
Thuật toán Luhn, còn được gọi là thuật toán "modulus 10" hoặc "mod 10", là một công thức kiểm tra đơn giản được sử dụng để xác thực nhiều loại số nhận dạng, chẳng hạn như số thẻ tín dụng, Số An Sinh Xã Hội Canada, số IMEI và số Nhà Cung Cấp Quốc Gia tại Hoa Kỳ. Máy tính này cho phép bạn xác thực các số bằng cách sử dụng thuật toán Luhn và tạo ra các số hợp lệ vượt qua kiểm tra Luhn.
Thuật toán Luhn hoạt động như sau:
Dưới đây là một hình ảnh minh họa cho thuật toán Luhn:
Thuật toán Luhn có thể được biểu diễn toán học như sau:
Gọi là chữ số thứ , đếm từ chữ số bên phải (không bao gồm chữ số kiểm tra) và di chuyển sang bên trái. Sau đó, chữ số kiểm tra được chọn sao cho:
Trong đó là phép toán modulo.
Thuật toán Luhn có nhiều ứng dụng trong các lĩnh vực khác nhau:
Mặc dù thuật toán Luhn được sử dụng rộng rãi, vẫn có các thuật toán kiểm tra khác cho các mục đích khác nhau:
Thuật toán Luhn được tạo ra bởi Hans Peter Luhn, một nhà khoa học máy tính của IBM, vào năm 1954. Luhn là một người tiên phong trong lĩnh vực khoa học thông tin và được ghi nhận với nhiều phát minh, bao gồm hệ thống lập chỉ mục KWIC (Từ Khóa Trong Ngữ Cảnh).
Thuật toán này ban đầu được thiết kế để bảo vệ chống lại các lỗi vô tình, không phải các cuộc tấn công ác ý. Điều quan trọng cần lưu ý là trong khi thuật toán Luhn có thể phát hiện nhiều lỗi phổ biến, nó không phải là một hình thức mã hóa an toàn và không nên được dựa vào cho các mục đích bảo mật dữ liệu.
Mặc dù đã có tuổi đời lâu, thuật toán Luhn vẫn được sử dụng rộng rãi nhờ vào tính đơn giản và hiệu quả trong việc phát hiện các lỗi sao chép phổ biến.
Dưới đây là một số ví dụ mã để thực hiện thuật toán Luhn trong các ngôn ngữ lập trình khác nhau:
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## Ví dụ sử dụng:
22print(luhn_validate(4532015112830366)) # True
23print(luhn_validate(4532015112830367)) # False
24print(generate_valid_number(16)) # Tạo ra một số hợp lệ 16 chữ số
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// Ví dụ sử dụng:
29console.log(luhnValidate(4532015112830366)); // true
30console.log(luhnValidate(4532015112830367)); // false
31console.log(generateValidNumber(16)); // Tạo ra một số hợp lệ 16 chữ số
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)); // Tạo ra một số hợp lệ 16 chữ số
47 }
48}
49
Khi thực hiện thuật toán Luhn, hãy xem xét các trường hợp biên và các xem xét đặc biệt sau:
Kiểm Tra Đầu Vào: Đảm bảo rằng đầu vào là một chuỗi số hợp lệ. Các ký tự không phải số nên được xử lý một cách thích hợp (hoặc bị loại bỏ hoặc coi là đầu vào không hợp lệ).
Số 0 Đầu: Thuật toán nên hoạt động chính xác với các số có số 0 đầu.
Số Lớn: Hãy chuẩn bị để xử lý các số rất dài có thể vượt quá khả năng của các kiểu số nguyên tiêu chuẩn trong một số ngôn ngữ lập trình.
Đầu Vào Trống: Định nghĩa cách thực hiện của bạn nên xử lý các chuỗi trống hoặc đầu vào null.
Tập Ký Tự Không Chuẩn: Trong một số ứng dụng, bạn có thể gặp các số được biểu diễn bằng các ký tự ngoài phạm vi tiêu chuẩn 0-9. Định nghĩa cách xử lý những điều này.
Xem Xét Hiệu Suất: Đối với các ứng dụng cần xác thực một số lượng lớn đầu vào nhanh chóng, hãy xem xét tối ưu hóa việc thực hiện thuật toán.
Số Thẻ Tín Dụng Hợp Lệ:
Số Thẻ Tín Dụng Không Hợp Lệ:
Số An Sinh Xã Hội Canada Hợp Lệ:
Số IMEI Không Hợp Lệ:
Để xác minh việc thực hiện thuật toán Luhn, bạn có thể sử dụng các trường hợp kiểm tra sau:
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 # Kiểm tra các số được tạo ra
8 for _ in range(10):
9 assert luhn_validate(generate_valid_number(16)) == True
10
11 print("Tất cả các bài kiểm tra đều đã vượt qua!")
12
13test_luhn_algorithm()
14