十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
2121校验应该就是利用Luhn算法
成都创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站建设、成都做网站、屯昌网络推广、微信小程序开发、屯昌网络营销、屯昌企业策划、屯昌品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联为所有大学生创业者提供屯昌建站搭建服务,24小时服务热线:18980820575,官方网址:www.cdcxhl.com
Luhn 算法或是Luhn
公式,也被称作“模10算法”。它是一种简单的校验公式,一般会被用于身份证号码,IMEI号码,美国供应商识别号码,或是加拿大的社会保险号码的验证。该算法是由IBM的科学家Hans
Peter Luhn所创造,于1954年1月6日提出该专利的申请,并于1960年8月23日被授予,在美国的专利号为2950048。
该算法一直都被大家所公用,并且时至今日应用也很广泛。它被指定在ISO/IEC7812-1。它的目的不是成为一种加密安全的哈希函数;它的目的是防止意外出现的错误,而不是恶意攻击。很多信用卡和众多的政府身份识别号码都使用该算法从一系列的随机数字中提取有效的数字。
优点和缺点
Luhn
算法会检测到任何单码的错误以及几乎所有的相邻数字换位的错误。但是它不会检测两个数字序列09转90的错误(反之亦然)。它会检测到十分之七的相同双位数错误(不会检测到22和55的互换,33和66的互换,44和77的互换)。其他更复杂的检查数字算法,如费尔赫夫算法,可以检测出更多的转录错误。模N的Luhn算法是Luhn算法的一个扩展,支持非数字字符串。因为该算法采取了从右向左的方式,而且零位会影响计算的结果。只有当零位造成了数位的移动或是用零来填充一串数字的开头时才不会影响计算结果的生成。因此不论在将1234用零填充为0001234之前或是之后,使用Luhn算法得到的结果都是一样的。
该算法在美国专利上是为了给手持或是机械设备计算校验码。所以它必须尽可能的简单。
非正式的解释
该公式会通过校验码对一串数字进行验证。校验码通常会被加到账户号码中,从而拼合成一个完整的账户号码。拼合后的账户号码要通过以下的测试:
1.从校验位开始计数(校验位一般添加在账户的最后面),按从右向左的顺序,将偶数都乘以2.
2.将得到的结果相加起来(例如:10=1+0=1,14=1+4=5,也有的说法是若是乘2的结果是两位数的话,那么就直接减去9,和之前位数拆开相加的结果是一样的),然后再与原数字串的奇数位相加。
3.如果加起来的和模10后为0(也就是相加的结果是以0结尾的,10的倍数),那么这个数字串根据Luhn算法来说就是有效的,反之就是无效的。
假设一个字符串为“7992739871”,我们为其加上一个校验位,最后组成的数字为7992739871x:
账户号码: 7 9 9
2 7 3
9 8 7 1 x
将偶数位乘以2:7 18 9 4 7 6 9
16 7 2
x
相加后的数字: 7 9 9 4 7 6 9 7 7
2 =67
校验码x是通过将相加后的数字乘以9后,在进行模10计算(那么就是:(67*9)mod10,也有的说法是取比相加的和最小的10的整数倍数字,其实结果都是一样的)。通俗地说:
1.计算所有位数的和(67)。
2.将其乘以9(603)。
3.取最后一位数字(3)。
4.得到的结果就是校验位。
另外一种得到校验位的方法:先计算所有位数的和,用10减去所有位数和模10的结果。(67的个位是7;10-7=3即为校验位)。通俗地说:
1.计算所有位数的和(67)。
2.取个位数(7)。
3.用10减去个位数(3)。
4.得到的结果就是校验位。
这样,我们得到的完整的账户号码是:7992739871x。
下面的每一个数字 79927398710, 79927398711, 79927398712, 79927398713, 79927398714,
79927398715, 79927398716, 79927398717, 79927398718,
79927398719都给以用如下的方法进行验证。
1.从最右边开始计算,将偶数位都乘以2:(1*2)=2,(8*2)=16,(3*2)=6,(2*2)=4,(9*2)=18
2.将每一位数字加起来:x(校验位)+(2)+7+(1+6)+9+(6)+7+(4)+9+(1+8)+7=X+67.
3.如果得到的结果是10的倍数,那么这个账户号码就可能是有效的。需要注意的是3就是唯一的可以使得和(67+x)是10的整数倍的个位数。
4.因此,以上的所有账户除了79927398713 是有效的以外,其他均为无效的账户。
校验位的验证的代码实现
以下通过Python来实现的:
def luhn_checksum(card_number):
def digits_of(n):
return [int(d) for d in str(n)]
digits = digits_of(card_number)
odd_digits = digits[-1::-2]
even_digits = digits[-2::-2]
checksum = 0
checksum += sum(odd_digits)
for d in even_digits:
checksum += sum(digits_of(d*2))
return checksum % 10
def is_luhn_valid(card_number):
return luhn_checksum(card_number) == 0
校验位的计算
上面的算法检查输入校验位的有效性。计算校验位需要一个小的适应算法,即:
1.切换奇/偶乘法。
2.如果得到的和(sum)模10等于0的话,那么校验码就是0。
3.否则,校验码就等于10减去得到的和模10(10 - (sum mod 10))
def calculate_luhn(partial_card_number):
return 10 - luhn_checksum(int(partial_card_number) * 10)
LUHN是一个算法,它的就要作用是为了计算信用卡等证件号码的合法性。我们用一个例子来看一下这个算法的工作过程:
假设我们有一个数4992 73 9871,这个数是没有带校验码的,算法的计算分为三步:
由最低位起每隔一位取一个数字,将这个数字乘2;
1*2=2 8*2=16 3*2=6 2*2=4 9*2=18
将数字中余下的数字和上面结果中的数字直接相加,得到结果B;
4 + 1+8 + 9 + 4 + 7 + 6 + 9 + 1+6 + 7 + 2 = 64
生成校验码C=A-B,其中A是比B大的10倍数中最小的数字,如B=86,则A=90;如B=34,A=40;
6 = 70-64
将校验码加在原来数字的后面生成合法的帐户密码;
4992 73 9871 6
#includestdio.h
#includestring.h
void luhn(char c[20]);int main(void)
{
char c[20];
while(1)
{
printf("输入信用卡号\n");
gets(c);
if(strlen(c) != 16)
printf("长度错误\n");
else
luhn(c);
}
return 0;
}void luhn(char c[20])
{
int i,j;
int num=0;
for(i=0;i16;i++)
{
if(0 == i%2)
{
if((c[i]-48)*2 9)
num +=(c[i]-48)*2-9;
else
num +=(c[i]-48)*2;
}
else
num +=c[i]-48;
}
if(0 == num%10)
printf("合法\n\n");
else
printf("不合法\n\n");
} 有疑问请说