Luhn 算法数字验证与生成工具

使用 Luhn 算法验证和生成数字,该算法通常用于信用卡号码、加拿大社会保险号码和其他身份证明号码。测试一个数字是否通过 Luhn 检查,或生成符合该算法的有效数字。

Luhn算法计算器

📚

文档

Luhn 算法计算器

介绍

Luhn 算法,也称为“模 10”或“模 10”算法,是一种简单的校验和公式,用于验证各种识别号码,例如信用卡号码、加拿大社会保险号码、IMEI号码和美国国家提供者标识符号码。此计算器允许您使用 Luhn 算法验证号码并生成通过 Luhn 检查的有效号码。

Luhn 算法的工作原理

Luhn 算法的工作原理如下:

  1. 从右侧的数字开始(不包括校验位),向左移动,双倍每个第二位数字的值。
  2. 如果此双倍操作的结果大于 9,则从结果中减去 9。
  3. 将结果序列中的所有数字相加。
  4. 如果总和模 10 等于 0(如果总和以零结尾),则该号码根据 Luhn 公式是有效的;否则,它是无效的。

以下是 Luhn 算法的可视化表示:

1. 双倍每个第二位数字 2. 求和数字(对于双倍 > 9 的数字为 9) 3. 计算总和 4. 检查总和 % 10 == 0

公式

Luhn 算法可以用数学公式表示如下:

did_i 为第 ii 位数字,从右侧数字开始(不包括校验位)并向左移动。然后选择校验位 d0d_0 使得:

(2d2nmod9+d2n1+2d2n2mod9+d2n3++2d2mod9+d1+d0)mod10=0(2d_{2n} \bmod 9 + d_{2n-1} + 2d_{2n-2} \bmod 9 + d_{2n-3} + \cdots + 2d_2 \bmod 9 + d_1 + d_0) \bmod 10 = 0

其中 mod\bmod 是模运算。

用例

Luhn 算法在不同领域有多种应用:

  1. 信用卡验证:大多数信用卡号码使用 Luhn 算法进行验证。
  2. 加拿大社会保险号码:Luhn 算法用于验证这些识别号码的有效性。
  3. IMEI号码:手机 IMEI号码包含一个由 Luhn 算法验证的校验位。
  4. 国家提供者标识符 (NPI)号码:在美国医疗系统中使用,这些号码通过 Luhn 算法进行验证。
  5. ISBN:一些 ISBN-10号码使用 Luhn 算法的变体进行验证。

替代方案

虽然 Luhn 算法被广泛使用,但还有其他校验和算法用于不同的目的:

  1. Damm 算法:另一种校验位算法,可以检测所有单个数字错误和所有相邻交换错误。
  2. Verhoeff 算法:一种更复杂的校验和算法,可以捕获所有单个数字错误和大多数交换错误。
  3. ISBN-13 校验位:使用与 ISBN-10 不同的算法,该算法基于 Luhn 算法。

历史

Luhn 算法由 IBM 计算机科学家汉斯·彼得·吕恩于 1954 年创建。吕恩是信息科学领域的先驱,因多项创新而闻名,包括 KWIC(上下文中的关键字)索引系统。

该算法最初旨在防止意外错误,而非恶意攻击。重要的是要注意,虽然 Luhn 算法可以检测许多常见错误,但它不是一种安全的加密形式,不应依赖于数据安全目的。

尽管年代久远,Luhn 算法仍因其简单性和有效性而广泛使用,能够捕获常见的抄写错误。

实现示例

以下是用不同编程语言实现 Luhn 算法的一些代码示例:

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## 示例用法:
22print(luhn_validate(4532015112830366))  # True
23print(luhn_validate(4532015112830367))  # False
24print(generate_valid_number(16))  # 生成一个有效的 16 位数字
25

边缘案例和特殊考虑

在实现 Luhn 算法时,请考虑以下边缘案例和特殊考虑:

  1. 输入验证:确保输入是有效的数字字符串。应适当处理非数字字符(可以删除或视为无效输入)。

  2. 前导零:算法应能正确处理具有前导零的数字。

  3. 大数字:准备处理可能超出某些编程语言标准整数类型容量的非常长的数字。

  4. 空输入:定义您的实现应如何处理空字符串或 null 输入。

  5. 非标准字符集:在某些应用中,您可能会遇到以标准 0-9 范围之外的字符表示的数字。定义这些应如何处理。

  6. 性能考虑:对于需要快速验证大量输入的应用,请考虑优化算法实现。

数值示例

  1. 有效的信用卡号码:

    • 号码:4532015112830366
    • Luhn 检查:有效
  2. 无效的信用卡号码:

    • 号码:4532015112830367
    • Luhn 检查:无效
  3. 有效的加拿大社会保险号码:

    • 号码:046 454 286
    • Luhn 检查:有效
  4. 无效的 IMEI号码:

    • 号码:490154203237518
    • Luhn 检查:无效

测试用例

为了验证 Luhn 算法的实现,您可以使用以下测试用例:

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    # 测试生成的数字
8    for _ in range(10):
9        assert luhn_validate(generate_valid_number(16)) == True
10    
11    print("所有测试通过!")
12
13test_luhn_algorithm()
14

参考文献

  1. Luhn, H. P. (1960). "计算机验证号码". 美国专利 2,950,048.
  2. Gallian, Joseph. "识别号码的数学". 《大学数学杂志》,第 22 卷,第 3 期,1991 年,第 194–202 页。JSTOR,www.jstor.org/stable/2686878.
  3. "ISO/IEC 7812-1:2017". 国际标准化组织。检索于 2024 年 8 月 2 日。
  4. Knuth, Donald. "计算机程序设计的艺术,第二卷:半数值算法". Addison-Wesley, 1997.