Luhn算法的实现

新手上路,请多包涵

我正在尝试实现信用卡号的简单验证。我 在维基百科上 读到了 Luhn 算法:

  1. 从最右边的校验位开始向左移动,每第二位的值加倍。
  2. 将乘积的数字(例如,10: 1 + 0 = 1、14: 1 + 4 = 5)与原始数字的未加倍数字相加。
  3. 如果总模 10 等于 0(如果总和以零结尾),则根据 Luhn 公式该数字有效;否则无效。

在维基百科上,Luhn 算法的描述非常容易理解。但是,我还在 Rosetta Code其他地方(已存档)看到了 Luhn 算法的其他实现。

这些实现工作得很好,但我对为什么他们可以使用数组来完成工作感到困惑。他们使用的数组似乎与Luhn算法无关,我看不出他们是如何实现维基百科上描述的步骤的。

他们为什么使用数组?它们有什么意义,它们如何用于实现维基百科描述的算法?

原文由 Mithril 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 529
2 个回答

数组 [0,1,2,3,4,-4,-3,-2,-1,0] 用作查找数组,用于查找 0-9 中的数字与其值的 2 倍数字和之间的差异。例如,对于数字 8,8 和 (2*8) = 16 -> 1+6 = 7 之间的差是 7-8 = -1。

这是图形表示,其中 {n} 代表 n 的数字的总和

[{0*2}-0, {1*2}-1, {2*2}-2, {3*2}-3, {4*2}-4, {5*2}-5, {6*2}-6, {7*2}-7....]
   |       |        |         |        |        |       |         |
[  0  ,    1    ,   2    ,    3  ,     4   ,   -4  ,   -3   ,    -2  ....]

您列出的算法只是对所有数字求和,对于每个偶数点数字,使用数组查找差异,并将其应用于总和。

原文由 yngccc 发布,翻译遵循 CC BY-SA 3.0 许可协议

不幸的是,上面的代码都不适合我。但我在 GitHub 上找到了一个可行的解决方案

// takes the form field value and returns true on valid number
function valid_credit_card(value) {
// accept only digits, dashes or spaces
    if (/[^0-9-\s]+/.test(value)) return false;

// The Luhn Algorithm. It's so pretty.
    var nCheck = 0, nDigit = 0, bEven = false;
    value = value.replace(/\D/g, "");

    for (var n = value.length - 1; n >= 0; n--) {
        var cDigit = value.charAt(n),
            nDigit = parseInt(cDigit, 10);

        if (bEven) {
            if ((nDigit *= 2) > 9) nDigit -= 9;
        }

        nCheck += nDigit;
        bEven = !bEven;
    }

    return (nCheck % 10) == 0;
}

原文由 Ron 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏