luhn算法

在codewars刷js题时,碰到一个luhn算法题,很简单,但如何写的优雅和简洁却很考验功力。先介绍下luhn算法吧:

LUHN算法,主要用来计算信用卡等证件号码的合法性。

1、从卡号最后一位数字开始,偶数位乘以2,如果乘以2的结果是两位数,将两个位上数字相加保存。

2、把所有数字相加,得到总和。

3、如果信用卡号码是合法的,总和可以被10整除。

我的代码如下:

function validate(n){
  var arr = parseToArray(n);
  arr = walkToReplace(arr);
  var sum = sumOfArray(arr);
  return sum%10===0;
}

function parseToArray(n){
  n = ‘‘ + n;
  return n.split("").reverse();
}

function walkToReplace(arr){
  for(var i=0,l=arr.length; i<l; i++){
    if((i+1)%2===0){
      arr[i] = 2*arr[i] > 9 ? 2*arr[i]-9 : 2*arr[i];
    }
  }
  return arr;
}

function sumOfArray(arr){
  return eval(arr.join("+"));
}

代码其实也不长,比70%以上的解决方法的代码要短,但感觉有些死板,而且也体现不出技巧性,只能说中规中矩的代码。

最佳解决方案如下:

function validate(n){
  var sum = 0;

  while (n > 0) {
    var a = n % 10;
    n = Math.floor(n / 10);

    var b = (n % 10) * 2;
    n = Math.floor(n / 10);

    if (b > 9) {
      b -= 9;
    }

    sum += a + b;
  }

  return sum % 10 == 0;
}

读完后不禁拍案叫绝,其实该方法用到的算法技巧也非常简单,但关键是用的很妙,大部分的解决方案是先替换值,然后再求和,我的解决方案也是如此。然而该方法,将值的替换与求和在一个while循环里就完成了,而且代码简短易读,确实是很很值得称赞。

该方法还为“求一个n位数字的各位数之和”这种问题提供了一种思路,属于reduce的一种。

时间: 2024-11-06 00:01:17

luhn算法的相关文章

Luhn算法?验证银行卡是否有效

Luhn算法 1.从卡号最后一位数字开始,逆向将奇数位(1.3.5等等)相加. 2.从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去9),再求和. 3.将奇数位总和加上偶数位总和,结果应该可以被10整除. function checkCard($card) { $num = 0; $card = str_split(trim($card)); krsort($card); $i = 1; foreach($card as $val){ if ($i % 2) {/

Luhn 算法-- 信用卡号码的校验

信用卡号码的校验用的是Luhn算法: 旧IBM的工程师Hans Peter Luhn在1954年发明的. 当时被申请为专利,现在已经公开,进入公共知识领域,成为国际标准组织的一项标准: ISO/EC 7812-1. 从卡号最后一位数字开始,逆向将奇数位数字相加求和 从卡号最后一位数字开始,逆向将偶数位数字,先乘以2,如果乘积为两位数,则减去9 (或两位数字求和),再求和 将奇数位总和加上偶数位总和,结果可以被10整除. 1 int luhnCheck(vector<int> &digi

判断用户输入的银行卡号是否正确--基于Luhn算法的格式校验

开发中,有时候,为了打造更好的用户体验,同时减轻服务器端的压力,需要对于一些如,手机号码,银行卡号,身份证号码进行格式校验 下面是判断银行卡号输入是否正确的代码(基于Luhn算法的格式校验): iOS代码: /** *  银行卡格式校验 * *  @param cardNo 银行卡号 * *  @return */ + (BOOL) checkCardNo:(NSString*) cardNo{ int oddsum = 0;     //奇数求和 int evensum = 0;    //偶

银行卡号码的校验规则(Luhn算法/模10算法)

银行卡校验 可以用于前端需要用户输入银行卡时做初步校验 银行卡号码的校验采用Luhn算法,校验过程大致如下: 从右到左给卡号字符串编号,最右边第一位是1,最右边第二位是2,最右边第三位是3-. 从右向左遍历,对每一位字符t执行第三个步骤,并将每一位的计算结果相加得到一个数s. 对每一位的计算规则:如果这一位是奇数位,则返回t本身,如果是偶数位,则先将t乘以2得到一个数n,如果n是一位数(小于10),直接返回n,否则将n的个位数和十位数相加返回. 如果s能够整除10,则此号码有效,否则号码无效.

[技术栈]C#利用Luhn算法(模10算法)对IMEI校验

1.Luhn算法(模10算法) 通过查看ISO/IEC 7812-1:2017文件可以看到对于luhn算法的解释,如下图: 算法主要分为三步: 第一步:从右边第一位(最低位)开始隔位乘2: 第二步:把第一步所得的每一个数字加入到原来的数中,比如9*2=18,为1+8: 第三步:用以0结尾且大于第二步所获得的数的和的最小整数减去第二步所获得的合即可以获得校验位,如70-67=3,3即为校验位,如果第二步所有数字的和以0结尾,比如30.40.50等,那么校验为0: 2.IMEI校验 IMEI码由GS

Luhn算法检验和验证

Luhn检验和验证 Luhn公式是一种广泛使用的系统,用于对标识号进行验证.它根据原始标识号,把每隔一个数字的值扩大一倍.然后把各个单独数字的值加在一起(如果扩大一倍后的值为2个数字,就把这两个数字分别相加).如果相加之后可以被10整除,那么这个标识号就是合法的. 编写一个程序,接受一个任意长度的标识号,并根据Luhn公式确定这个标识号是否合法.这个程序在读取下一个字符之前必须处理之前所读取的那个字符. 过程有些复杂,在此上传一张图片以供各位理解: 记住:最终标识号的检验和应该能够被10整除,或

OJ刷题---信用卡号校验(Luhn算法)

题目要求: 输入代码: #include<iostream> #include<cstdio> #include<stdlib.h>//导入C语言头文件,将要用到其中的函数 using namespace std; void getln(int a[])//输入数据的同时将数据反置并存放在数组a中 { char p=getchar(); if(p!='\n') getln(a-1);//当不按下回车键时递归输入 else return ; int x=strtol(&a

算法系列4——Luhn

Luhn算法由IBM的Hans Peter Luhn发明,又称为"模10"算法,是一种简单的校验和算法,用来验证识别号,一般会被用于身份证号码,信用卡号.IMEI号.社会保险号的验证.它的算法简单,并只采用最后一位数字作为校验位,可以有效防止偶然的输入性错误. Luhn算法只能用于简单的校验,不能用于加密算法.Luhn算法可以检测到以下输入性错误:所有的单位数字错误,如 210写作215:能检测到绝大多数的临位错位,比如315写作351,但是只有两位的情况下无法检测,比如09写作90:

C语言实现Luhn 校验

LUHN算法,主要用来计算信用卡等证件号码的合法性. 1.从卡号最后一位数字开始,偶数位乘以2,如果乘以2的结果是两位数,将两个位上数字相加保存. 2.把所有数字相加,得到总和. 3.如果信用卡号码是合法的,总和可以被10整除 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, const char * argv[]) { char num[30]; while(ge