如何将字节加在一起并根据 python 中的校验和验证它们

您如何计算传入字节的校验和以查看它是否是有效数据包?目前我正在读取字节并对它们进行解码并接收信息,但在我这样做之前我希望能够根据校验和验证它以确保我没有收到任何无效/损坏的数据包。


这是我目前拥有的


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 ser


class 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] = value


if __name__ == "__main__":

    print("BATTERY MONITOR")

    bmv700 = VictronBmv700("COM17", 19200)

    bmv700.getBMVInfo()


翻阅古今
浏览 118回答 2
2回答

千万里不及你

发帖者似乎正在尝试从 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&nbsp; &nbsp; | Meaning&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |+===============+======================================================================================+| <Newline>&nbsp; &nbsp; &nbsp;| A carriage return followed by a line feed (0x0D, 0x0A).&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |+---------------+--------------------------------------------------------------------------------------+| <Field-Label> | An arbitrary length label that identifies the field.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;||&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| Where applicable, this will be the same as the label that is used on the LCD.&nbsp; &nbsp; &nbsp; &nbsp; |+---------------+--------------------------------------------------------------------------------------+| <Tab>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| A horizontal tab (0x09).&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|+---------------+--------------------------------------------------------------------------------------+| <Field-Value> | The ASCII formatted value of this field.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;||&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 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'&nbsp; &nbsp; b'H4\t0\r\n'&nbsp; &nbsp; b'H6\t-9001\r\n'&nbsp; &nbsp; b'H8\t28403\r\n'&nbsp; &nbsp; b'H10\t0\r\n'&nbsp; &nbsp; b'H12\t0\r\n'&nbsp; &nbsp; b'H18\t87\r\n'&nbsp; &nbsp; b'PID\t0x203\r\n'&nbsp; &nbsp; b'I\t0\r\n'&nbsp; &nbsp; b'CE\t0\r\n'&nbsp; &nbsp; b'TTG\t-1\r\n'&nbsp; &nbsp; b'Relay\tOFF\r\n'&nbsp; &nbsp; b'BMV\t700\r\n'&nbsp; &nbsp; b'Checksum\t\xd6')请注意,我\r\n在开头添加了,并从块的末尾删除了它们,这样最后一个字节就是块的校验和。现在,我们可以计算块的校验和:>>> sum(block) % 256213这应该是零。因此,可能存在一些传输问题,或者他们计算校验和的方式可能与他们在文档中所说的不同。新数据后编辑。这是我用来检查您发布的所有块的代码: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&nbsp;# 2 characters in the last line that is readmessage = bmvdata.readline()while True:&nbsp; &nbsp; # Note that we cannot decode yet, since the Checksum value may not be a valid utf8 character&nbsp; &nbsp; message = bmvdata.readline()&nbsp; &nbsp; # we save the message in the current block before any preprocessing&nbsp; &nbsp; current_block.append(message)&nbsp; &nbsp; #splitting on tabs (as bytes !!)&nbsp; &nbsp; message_parts = message.split(b'\t')&nbsp; &nbsp; if len(message_parts) > 1:&nbsp; &nbsp; &nbsp; &nbsp; key = message_parts[0].decode('utf8')&nbsp; # here it is safe to decode the key&nbsp; &nbsp; &nbsp; &nbsp; value = message_parts[1].rstrip()&nbsp; #stripping \r\n after the value&nbsp; &nbsp; if key == 'Checksum':&nbsp; &nbsp; &nbsp; &nbsp; block_chars = b''.join(current_block)&nbsp; &nbsp; &nbsp; &nbsp; checksum = sum(block_chars) % 256&nbsp; &nbsp; &nbsp; &nbsp; print('Retrieved&nbsp; checksum', value[-1])&nbsp; &nbsp; &nbsp; &nbsp; print('Calculated checksum', checksum)&nbsp; &nbsp; &nbsp; &nbsp; print('----')&nbsp; &nbsp; &nbsp; &nbsp; # reset the block&nbsp; &nbsp; &nbsp; &nbsp; current_block = []奇怪的是,对于第一次运行,您总是得到等于检索到的计算值 + 1,但在第二次运行中却没有。因此,可能存在一些传输问题。

慕桂英546537

下面的代码比较了两个文件,在这种情况下,正如提问者提到的校验和:&nbsp;bmvdata = batteryConnect(self.port,self.baudrate)&nbsp;bmvdata.flushInput()&nbsp;print(bmvdata.readline())它是在hashlib的帮助下完成的import hashlib#File 1 = checksumhasher1 = hashlib.md5()#afile1 = open('checksum', 'rb')buf1 = bmvdata.read()#buf1 = afile1.read()a = hasher1.update(buf1)md5_a=(str(hasher1.hexdigest()))#File 2hasher2 = hashlib.md5()afile2 = open('incoming-byte', 'rb')buf2 = afile2.read()b = hasher2.update(buf2)md5_b=(str(hasher2.hexdigest()))#Compare md5if(md5_a==md5_b):&nbsp; &nbsp; print("Yes")else:&nbsp; &nbsp; print("No")
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python