Thuật toán Luhn, còn được gọi là công thức Luhn hay phương pháp Modulus 10, là một thuật toán đơn giản được sử dụng để kiểm tra tính hợp lệ của một số nhận dạng, thường là số thẻ tín dụng, số điện thoại, và các số định danh tương tự. Thuật toán này được phát triển bởi Hans Peter Luhn, một nhà khoa học máy tính người Đức làm việc tại IBM vào năm 1954.
Mục đích của thuật toán Luhn là phát hiện lỗi nhập liệu, như việc nhập sai một chữ số hoặc hoán đổi vị trí của hai chữ số liền kề. Tuy nhiên, thuật toán này không phải là một phương pháp mã hóa an toàn và không thể ngăn chặn tất cả các hành vi gian lận.
Bước 1: Nhân đôi giá trị của các chữ số xen kẽ bắt đầu từ chữ số bên phải đầu tiên (tức chữ số đơn vị).
Bước 2: Cộng các chữ số riêng lẻ nếu kết quả lớn hơn 9 trong các tích thu được khi nhân đôi chữ số ở Bước 1
Bước 3: Tính "bù hai chữ số" của chữ số đơn vị của tổng.
Example: Chúng ta sẽ check 1 thẻ credit card có number account như sau: 6123 4512 3456 789x
6 | 1 | 2 | 3 | 4 | 5 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
x2 | 1 | x2 | 1 | x2 | 1 | x2 | 1 | x2 | 1 | x2 | 1 | x2 | 1 | x2 | |
1+2 | 1 | 4 | 3 | 8 | 5 | 2 | 2 | 6 | 4 | 1+0 | 6 | 1+4 | 8 | 1+8 | = 67 |
Tính "Bù hai chữ số" của chữ số đơn vị của tổng.
Ta có: 70 - 67 = 3
Vậy: 6123 4512 3456 7893 đáp ứng thuật toán Luhn
Vì vậy ta có thể viết thuật toán Check Luhn Algorithm bằng python như sau:
def generate_credit_card_number(): # Generate the first 10 digits randomly prefix = "556883" account_number = str(random.randint(0, 999999999)).zfill(9) card_number = prefix + account_number # Calculate the Luhn checksum checksum = 0 for i, digit in enumerate(card_number): if i % 2 == 0: # Double every other digit, starting from the right doubled_digit = int(digit) * 2 if doubled_digit > 9: # If the result is a two-digit number, add the digits together doubled_digit = int(str(doubled_digit)[0]) + int(str(doubled_digit)[1]) checksum += doubled_digit else: # Add the other digits together checksum += int(digit) # Add the checksum digit to the end of the card number if checksum % 10 == 0: card_number += "0" else: card_number += str(10 - (checksum % 10)) # Generate the CCV code (3 digits) ccv = str(random.randint(0, 999)).zfill(3) # Generate the expiration date (MM/YY format) now = datetime.datetime.now() expiration_year = now.year + random.randint(1, 6) expiration_month = random.randint(1, 12) if expiration_month < 10: expiration_month = "0" + str(expiration_month) else: expiration_month = str(expiration_month) expiration_date = expiration_month + "/" + str(expiration_year)[2:] return (card_number, ccv, expiration_date)