亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將字節加在一起并根據 python 中的校驗和驗證它們

如何將字節加在一起并根據 python 中的校驗和驗證它們

翻閱古今 2022-11-29 15:57:55
您如何計算傳入字節的校驗和以查看它是否是有效數據包?目前我正在讀取字節并對它們進行解碼并接收信息,但在我這樣做之前我希望能夠根據校驗和驗證它以確保我沒有收到任何無效/損壞的數據包。這是我目前擁有的def batteryConnect(port, baudrate):    # establishing a serial connection    ser = serial.Serial(port=port, baudrate= baudrate, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE,timeout=3)    return serclass VictronBmv700:    def __init__(self,port,baudrate):        self.port = port        self.baudrate = baudrate        self.parameterDict = dict.fromkeys(["PID","V","I","P","CE","SOC","TTG","Alarm","Relay","AR","BMV","FW","H1","H2","H3",                                  "H4","H5","H6","H7","H8","H9","H10","H11","H12","H17","H18"])    def getBMVInfo(self):        bmvdata = batteryConnect(self.port,self.baudrate)        #getting the data        bmvdata.flushInput()        #getting the message then splitting the key, value pairs        while True:            print(bmvdata.readline())            message = bmvdata.readline().decode(encoding='utf-8',errors='ignore')            #splitting on tabs            message_parts = message.split('\t')            if len(message_parts) > 1:                key = message_parts[0]                value = message_parts[1].rstrip()  #stripping \r\n after the value                #updating deictionary based on keys and their values.                self.parameterDict[key] = valueif __name__ == "__main__":    print("BATTERY MONITOR")    bmv700 = VictronBmv700("COM17", 19200)    bmv700.getBMVInfo()
查看完整描述

2 回答

?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

發帖者似乎正在嘗試從 BMV700 電池監視器讀取數據。閱讀此處的論文,我們看到它使用文本協議通過串行接口進行通信:


2 文本協議

當沒有 VE.Direct 查詢發送到設備時,充電器會定期將人類可讀 (TEXT) 數據發送到串行端口。有關內容和信息可用性的詳細說明,請參閱“VE.Direct Protocol”文檔


摘自 HEX 協議 (BMV-7xx-HEX-Protocol-public.pdf)


查看 TEXT 協議的規范 (VE.Direct-Protocol-3.28.pdf),我們發現:


消息格式

該設備以 1 秒的間隔傳輸數據塊。每個字段都使用以下格式發送:


<Newline><Field-Label><Tab><Field-Value>

標識符定義如下:


+---------------+--------------------------------------------------------------------------------------+

| Identifier    | Meaning                                                                              |

+===============+======================================================================================+

| <Newline>     | A carriage return followed by a line feed (0x0D, 0x0A).                              |

+---------------+--------------------------------------------------------------------------------------+

| <Field-Label> | An arbitrary length label that identifies the field.                                 |

|               | Where applicable, this will be the same as the label that is used on the LCD.        |

+---------------+--------------------------------------------------------------------------------------+

| <Tab>         | A horizontal tab (0x09).                                                             |

+---------------+--------------------------------------------------------------------------------------+

| <Field-Value> | The ASCII formatted value of this field.                                             |

|               | The number of characters transmitted depends on the magnitude and sign of the value. |

+---------------+--------------------------------------------------------------------------------------+

這對應于您正在打印的數據,但有一個例外:該行以 開頭,\r\b但不以它們結尾。


然后,該文件提供了有關校驗和的詳細信息:


數據的完整性

統計數據分組為塊,并附加了校驗和。塊中的最后一個字段將始終是“校驗和”。該值是一個字節,不一定是可打印的 ASCII 字符。如果沒有傳輸錯誤,塊中所有字節的模 256 和將等于 0。發送包含不同字段的多個塊。


因此,在您作為輸出發布的摘錄中,您有兩個完整的塊和一個不完整的塊,因為最后一個塊缺少Checksum.


block = (b'\r\nH2\t0\r\n'

    b'H4\t0\r\n'

    b'H6\t-9001\r\n'

    b'H8\t28403\r\n'

    b'H10\t0\r\n'

    b'H12\t0\r\n'

    b'H18\t87\r\n'

    b'PID\t0x203\r\n'

    b'I\t0\r\n'

    b'CE\t0\r\n'

    b'TTG\t-1\r\n'

    b'Relay\tOFF\r\n'

    b'BMV\t700\r\n'

    b'Checksum\t\xd6')

請注意,我\r\n在開頭添加了,并從塊的末尾刪除了它們,這樣最后一個字節就是塊的校驗和。


現在,我們可以計算塊的校驗和:


>>> sum(block) % 256

213

這應該是零。因此,可能存在一些傳輸問題,或者他們計算校驗和的方式可能與他們在文檔中所說的不同。


新數據后編輯。


這是我用來檢查您發布的所有塊的代碼:


current_block = []

# it's unfortunate that lines start with `\r\n` rather than end with it

# we will read the first empty line separatey, and then include these 

# 2 characters in the last line that is read

message = bmvdata.readline()

while True:

    # Note that we cannot decode yet, since the Checksum value may not be a valid utf8 character

    message = bmvdata.readline()


    # we save the message in the current block before any preprocessing

    current_block.append(message)


    #splitting on tabs (as bytes !!)

    message_parts = message.split(b'\t')


    if len(message_parts) > 1:

        key = message_parts[0].decode('utf8')  # here it is safe to decode the key

        value = message_parts[1].rstrip()  #stripping \r\n after the value


    if key == 'Checksum':

        block_chars = b''.join(current_block)

        checksum = sum(block_chars) % 256

        print('Retrieved  checksum', value[-1])

        print('Calculated checksum', checksum)

        print('----')


        # reset the block

        current_block = []

奇怪的是,對于第一次運行,您總是得到等于檢索到的計算值 + 1,但在第二次運行中卻沒有。因此,可能存在一些傳輸問題。


查看完整回答
反對 回復 2022-11-29
?
慕桂英546537

TA貢獻1848條經驗 獲得超10個贊

下面的代碼比較了兩個文件,在這種情況下,正如提問者提到的校驗和:


 bmvdata = batteryConnect(self.port,self.baudrate)

 bmvdata.flushInput()

 print(bmvdata.readline())

它是在hashlib的幫助下完成的


import hashlib

#File 1 = checksum

hasher1 = hashlib.md5()

#afile1 = open('checksum', 'rb')

buf1 = bmvdata.read()

#buf1 = afile1.read()

a = hasher1.update(buf1)

md5_a=(str(hasher1.hexdigest()))

#File 2

hasher2 = hashlib.md5()

afile2 = open('incoming-byte', 'rb')

buf2 = afile2.read()

b = hasher2.update(buf2)

md5_b=(str(hasher2.hexdigest()))

#Compare md5

if(md5_a==md5_b):

    print("Yes")

else:

    print("No")


查看完整回答
反對 回復 2022-11-29
  • 2 回答
  • 0 關注
  • 104 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號