python如何计算校验码(校验码计算题)

发布时间:2022-11-14

本文目录一览:

  1. 身份证号码尾号的校验码是由什么公式计算出来的
  2. 什么是“2121”校验方法?
  3. 用Python校验身份证号码真伪
  4. [GPRMC校验位如何计算 python csdn](#GPRMC校验位如何计算 python csdn)

身份证号码尾号的校验码是由什么公式计算出来的

校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。 具体的公式举例说明为: 某男性公民身份号码本体码为34052419800101001,首先按照公式计算:∑(ai×Wi)(mod 11),其中,i表示号码字符从右至左包括校验码在内的位置序号;a[i]表示第i位置上的号码字符值;W[i]表示第i位置上的加权因子,其数值依据公式 W[i] = 2^(i-1) mod (11)计算得出。 则,设R=∑(a[i]×W[i])(mod 11) = 2,同时R的值 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 对应取值为 [1, X, 9, 8, 7, 6, 5, 4, 3, 2]。 计算结果为2的校验码为X,所以该人员的公民身份号码应该为 34052419800101001X。

扩展资料:

身份证号码的结构和形式:

  1. 号码的结构:公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
  2. 地址码:表示编码对象常住户口所在县(县级市、旗、区)的行政区划代码,按GB/T2260的规定执行。
  3. 出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
  4. 顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
  5. 校验码:根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。 参考资料来源:百度百科-身份证号码百度百科-身份证校验位

什么是“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的整数倍数字,其实结果都是一样的)。通俗地说:
  4. 计算所有位数的和(67)。
  5. 将其乘以9(603)。
  6. 取最后一位数字(3)。
  7. 得到的结果就是校验位。 另外一种得到校验位的方法:先计算所有位数的和,用10减去所有位数和模10的结果。(67的个位是7;10-7=3即为校验位)。通俗地说:
  8. 计算所有位数的和(67)。
  9. 取个位数(7)。
  10. 用10减去个位数(3)。
  11. 得到的结果就是校验位。 这样,我们得到的完整的账户号码是:7992739871x。 下面的每一个数字 79927398710, 79927398711, 79927398712, 79927398713, 79927398714, 79927398715, 79927398716, 79927398717, 79927398718, 79927398719都给以用如下的方法进行验证。
  12. 从最右边开始计算,将偶数位都乘以2:(12)=2,(82)=16,(32)=6,(22)=4,(9*2)=18
  13. 将每一位数字加起来:x(校验位)+(2)+7+(1+6)+9+(6)+7+(4)+9+(1+8)+7=X+67。
  14. 如果得到的结果是10的倍数,那么这个账户号码就可能是有效的。需要注意的是3就是唯一的可以使得和(67+x)是10的整数倍的个位数。
  15. 因此,以上的所有账户除了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)

用Python校验身份证号码真伪

这个算法都给了,应该比较简单吧。我也很菜,随意写了一个。异常没做,你可以自己加一下。做一些验证过滤。不知道随机是不是真是随意随机,我没有按照身份证规则做随机。是真的随机了18位。。。如果你有规则,也可以自己写一个。

import random
yushu = [x for x in range(0, 11)]
ma = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2', '1']
def yanzheng(nid):
    dicma = dict(zip(yushu, ma))
    sum = 0
    for x, y in enumerate(nid[:-1]):
        sum += ((2**(18 - x - 1)) % 11) * int(y)  # 17位对应系数相乘的和
    if nid[-1] == dicma[sum % 11]:  # 校验码对照
        return '%s True' % nid
    else:
        return '%s False' % nid
def readfile(fname):
    f = open(fname, 'rb')
    for line in f.readlines():
        print yanzheng(line.strip())
    f.close()
def randnum():
    idstr = ''
    for i in range(17):  # 前17位随机
        idstr += str(random.randint(0, 9))
    idstr += random.choice(ma)  # 最后一位从列表中随意一个,因为有X
    return idstr
if __name__ == "__main__":
    nid = raw_input('Please enter your ID: ')  # 用户输入ID,没做任何验证
    print yanzheng(nid)  # 验证身份证
    readfile('id.txt')  # 从文件读出来 再验证
    print yanzheng(randnum())  # 随机一个 在验证

GPRMC校验位如何计算 python csdn

如果是当作无符号整数来计算,则算法要简单很多,实际上都可以缩减为一句代码的事。如果是当作带符号整数来计算,则算法要复杂一下,要处理各种上溢出和下溢出的情形。正如文章开头指出的,不论使用哪种方式,最后的二进制表示都是一样的。 所以一般情况下可以使用无符号整数来计算校验和,简单快速。