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'\x01\x7F\xFF')  
  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM