0校验算法
‘壹’ 什么是“2121”校验方法
2121校验应该就是利用Luhn算法
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)
‘贰’ 校验算法的缺点
校验算法不是其他人工作的简单推广,它摒弃了把已有的方法 集中到一起的想法,而是探素使用简单的代数概念来解决问题 的方法。尽管思想是简单的,但是非常有创造性。然而,这个算 法目前可能不会有太多的实际应用。这是因为算法的运行时间 是0((log n)}),与Miller和Rabin设计的概率测试的0(log rz) 运行时间相比是相形见咄的。研究者们注意到如果某个猜想被 证明,算法可以在0((logn)')时间内运行,这样的改善将促进 实际的应用。研究者们还证明如果Sophie Germain素数具有期 望的分布,那么在时间估计中的指数12可以减少到5。当然如 果发现素数的分布并非如此,那将会有很大区别。 校检算法最重要的意义是作为一个理论结果,为这一领域 的研究奠定了基础。之后在技术上将会进行改进与完善,使之 更为实用。
‘叁’ 校验码的算法举例
按照中华人民共和国国家标准GB11643-1999规定中华人民共和国公民身份号码校验码的计算方法即为ISO 7064:1983.MOD 11-2校验码计算法。
假设某一17位数字是 17位数字 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 加权因子 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 368
计算17位数字各位数字与对应的加权因子的乘积的和S:1×7+2×9+3×10+4×5+5×8+6×4+7×2+8×1+9×6+0×3+1×7+2×9+3×10+4×5+5×8+6×4+7×2=368; 计算S÷11的余数T:368 mod 11=5; 计算(12-T)÷11的余数R,如果R=10,校验码为字母“X”;如果R≠10,校验码为数字“R”:(12-5)mod 11=7。 该17位数字的校验码就是7,聚合在一为123456789012345677。
加权因子公式为Wi=2^(n-1)(mod 11),n为数字序列从右到左的从1开始的顺序数。
序
ai 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 ?Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1 全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一位数字(或大写拉丁字母)校验码组成。校验码按下列公式计算: 8 C9=11-MOD(∑Ci×Wi,11) i=1 MOD-表示求余函数;i-表示代码字符从左至右位置序号;
Ci-表示第i位置上的代码字符的值,采用下列“代码字符集”所列字符;
C9-表示校验码;
Wi-表示第i位置上的加权因子,其数值如下表:
加权因子 i 1 2 3 4 5 6 7 8 Wi 3 7 9 10 5 8 4 2 当MOD函数值为1(即C9=10)时,校验码应用大写拉丁字母“X”表示;当MOD函数值为0(即C9=11)时,校验码仍用“0”表示;当C9的值为1至9时,校验码直接用C9的值表示。
‘肆’ 传输数据为0,怎么计算CRC校验码
接收方:使用相同的举歼槐生成码进行校验:接收到的字段/生成码(二进制除法) 如果能够除尽,则正确, 即得到正友的余数是改郑1001的话是正确的 进行异或运算时除数和被除数最高位对齐,按位异或。 110110000- 110010000=000100000- 110010= 010010- 11001= 01011 不等于 1001 所以有错误
‘伍’ CRC校验全解
这几天一直在看CRC校验算法。CRC版本众多,网站上实现算法一大坨,可一开始根本搞不清楚那个是哪个。连续上网络,哔哩哔哩,知乎看了很多解读CRC算法的,终于有了一些眉目,打算写下来,方便日后参考。
CRC算法核心其实只有一种,即二进制除法的实现橘清,版本众多的原因主要有以下几个原因:
CRC字段的长度
多项式公式
初始值
输出是否水平翻转
输入是否水平翻转
结果异或值
我绝大多数的文章都只谈到了CRC字段的长度和多项式公式,没有涉及剩余的三项在crc算法中的应用。
CRC字段的长度 ,字段越长,对于crc算法的校验能力越强。如果我们用出错的概率来评宏旦估校验能力的话。N长度的字段,他的校验能力为1/2**N。此处的运算符号采用Python语言中的含义。
一般而言,我们取的长度主要有8位,16位和32位。当然也有一些比较奇特的,4位,5位和6位,还有7位。
多项式公式 是我们二进制多项蔽伍扰式算法中的除数。不同的算法往往取的多项式是不一样的。
初始值 ,是指CRC字段的初始值。常常是从0和全是1中选择。
输入反转。 具体的操作方法实施将输入的数据按照字节为单位进行水平反转。比如01000001,翻转结果是10000010。
输出翻转 。输出翻转的操作与输入翻转操作是一样的。只是输出翻转是将整个CRC字段进行水平翻转。
结果异或值 ,是用来和 通过上述的算法算出来的结果 进行异或的一个数据值。如果这个值是0的话,那么就相当于没有进行异或。
为什么需要这么多看起来乱七八糟的种类呢。这些算法分别针对不同的数据的检验。针对不同的数据的特性,比如说某些数据,一开始就会有大量的零,如果不采用输入翻转或者初始值的话,那么这些0就对于校验结果没有任何影响。这就如我们想要的结果有出入了,我们希望校验结果和数据是一一对应的,并且是唯一的。如果不唯一那么,校验结果也就失去了意义。因此这么多算法的出现,主要原因就是为了适应不同的数据字符串的特点。
下面就是一些例子了。
验证网站: http://www.ip33.com/crc.html
‘陆’ 身份证号最后一位数字称之为校验码,校验码的计算方式是怎样的
按照相关规定,身份号是由17个数字和1个数字校验码组成的。而最后一位校验码,就是检查身份证是否正确的主要依据。它的计算方法,主要是由前17位乘以不同的系数,最后的总和除以11。在这种情况下,得到的余数,就是校验码。
那么我们在反推的时候,就可以用身份证号乘于系数,当最后得出的余数和末尾校验码不同时,就代表这个身份证,是一个假的身份证,不符合我们国家的标准。另外,余数对应的数字不同,并不是说余数就一定是最后一位身份证号码。
看到整个计算过程,我们会发现,想要得出校验码,并非一件易事。不过在计算中,有人可能会提出疑问,最终的除以为什么是取11,而不是其他数字。
其实这个问题的答案很简单,结合校验码的功能,11是最容易检测出问题的存在。同时,它可以覆盖到大多数身份证,方便进行校验。毕竟一个国家人口众多,校验码要做到尽可能覆盖所有人。
‘柒’ 校验码是怎么算出来的
身份证第18位(校验码)的计算方法
1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十闭洞七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
2、将这17位数字和系数相乘的结果相加。
3、用加出来和除以11,看余数是多少?
4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。
5、通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最带租后一位号码就是2。
例如:某男性蠢态兆的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。
首先我们得出前17位的乘积和是189,然后用189除以11得出的结果是17+2/11,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的数字是x。所以,可以判定这是一个合格的身份证号码。
‘捌’ 有谁知道IMEI号校验码的计算方法
IMEI校验码算法:
(1).将偶数位数字分别乘以2,分别计算个位数和十位数之和
(2).将奇数位携如数字相加,再加上上一步算得的辩芹启值
(3).如首慧果得出的数个位是0则校验位为0,否则为10减去个位数
如:35 89 01 80 69 72 41 偶数位乘以2得到5*2=10 9*2=18 1*2=02 0*2=00 9*2=18 2*2=04 1*2=02,计算奇数位数字之和和偶数位个位十位之和,得到 3+(1+0)+8+(1+8)+0+(0+2)+8+(0+0)+6+(1+8)+7+(0+4)+4+(0+2)=63 => 校验位 10-3 = 7