zoukankan      html  css  js  c++  java
  • python 计算校验和

    校验和是经常使用的,这里简单的列了一个针对按字节计算累加和的代码片段。其实,这种累加和的计算,将字节翻译为无符号整数和带符号整数,结果是一样的。

    使用python计算校验和时记住做截断就可以了。 这里仅仅是作为一个代码样本,权作标记,直接上代码

    '''
    Created on 2014年9月4日
    
    @author: lenovo
    '''
    import random
    
    '''
    实际计算校验和时,解释为无符号整数还是带符号整数,结果必然是一样的。因为基于补码方式存储,计算加法时都是按位加,然后该进位的就进位。
    只是最终的结果,如果是带符号整数,最高位会被解释符号位
    '''
    
    def char_checksum(data, byteorder='little'):
        '''
        char_checksum 按字节计算校验和。每个字节被翻译为带符号整数
        @param data: 字节串
        @param byteorder: 大/小端
        '''
        length = len(data)
        checksum = 0
        for i in range(0, length):
            x = int.from_bytes(data[i:i+1], byteorder, signed=True)
            if x>0 and checksum >0:
                checksum += x
                if checksum > 0x7F: # 上溢出
                    checksum = (checksum&0x7F) - 0x80 # 取补码就是对应的负数值
            elif x<0 and checksum <0:
                checksum += x
                if checksum < -0x80: # 下溢出
                    checksum &= 0x7F
            else:
                checksum +=x # 正负相加,不会溢出
            #print(checksum)    
        
        return checksum
        
    
    def uchar_checksum(data, byteorder='little'):
        '''
        char_checksum 按字节计算校验和。每个字节被翻译为无符号整数
        @param data: 字节串
        @param byteorder: 大/小端
        '''
        length = len(data)
        checksum = 0
        for i in range(0, length):
            checksum += int.from_bytes(data[i:i+1], byteorder, signed=False)
            checksum &= 0xFF # 强制截断
            
        return checksum
    

      

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

    下面是验证使用的例子,

    [python] view plain copy
     
    1. data1=bytes(b'x01x7FxFF')  
    2.     data2=bytes([random.randrange(0,256) for i in range(0, 10000)])  
    3.     assert(uchar_checksum(data1) == 127)  
    4.     assert(char_checksum(data1) == 127)  
    5.     assert((uchar_checksum(data2)&0xFF) == (char_checksum(data2)&0xFF))  
    6.     print('OK')  


    上面的算法也很容易推广到两个字节或者四个字节的校验和计算

    over

  • 相关阅读:
    [HAOI2012]高速公路(BZOJ2752)
    [SHOI2008]堵塞的交通traffic(BZOJ1018)
    AHOI2009 行星序列Seq (BZOJ1798)
    java注解问题
    回调方法举例
    log4j将日志文件保存到项目中
    ehCache+springMVC的简单实用
    MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
    mybatis配置log4j
    mybatis ---- 分页 (拦截器)
  • 原文地址:https://www.cnblogs.com/liangqihui/p/8523006.html
Copyright © 2011-2022 走看看