gpt4 book ai didi

python - 如何使用 Python 计算此 CRC?

转载 作者:行者123 更新时间:2023-12-05 08:20:24 29 4
gpt4 key购买 nike

我需要使用 Python 计算此 CRC,以便与 Aurora (ABB) 太阳能逆变器进行通信。

这是文档:http://www.drhack.it/images/PDF/AuroraCommunicationProtocol_4_2.pdf在最后一页中有计算 CRC 的说明,我需要在 python 中执行。

我的消息是

MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000")

结果应该是:

CRC_L = FF

CRC_H = 2C

然后我需要像这样发送带有 CRC 的消息:

MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000ff2c")

我怎样才能在 python 中做到这一点?谢谢!

这是我试过的代码:

message = "023b010000000000"

BccLo= int ("FF",16)
BccHi= int("FF", 16)

New = int(message, 16)

New = New ^ BccLo
Tmp=New << 4
New=Tmp ^ New
Tmp=New >> 5
BccLo=BccHi
BccHi= New ^ Tmp
Tmp=New << 3
BccLo=BccLo ^ Tmp
Tmp=New >> 4
BccLo=BccLo ^ Tmp

CRC_L = ~BccLo
CRC_H = ~BccHi

最佳答案

您需要将该算法应用于消息的每个字节。有点复杂的是,Aurora PDF 文件中给出的算法假定计算是使用 8 位无符号算法执行的。为了在 Python 中处理它,我们可以使用 0xff 位掩码。这是该代码的一个稍微优化的版本。

def crc_16(msg):
lo = hi = 0xff
mask = 0xff
for new in msg:
new ^= lo
new ^= (new << 4) & mask
tmp = new >> 5
lo = hi
hi = new ^ tmp
lo ^= (new << 3) & mask
lo ^= new >> 4
lo ^= mask
hi ^= mask
return hi << 8 | lo

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))

输出

2cff = 2c ff

上面的代码可以工作,但是有更简单的方法来计算 CRC。如果您需要计算很多 CRC,我们可以使用表格来加快该过程。

如维基百科Cyclic redundancy check文章提到,CRC 算法通常根据编码为十六进制数的多项式来指定。这是一个使用反向多项式表示的函数。

def crc_16_CCITT(msg):
poly = 0x8408
crc = 0xffff
for byte in msg:
for _ in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
return crc ^ 0xffff

为了加快速度,我们可以计算一个表。

def make_crc_table():
poly = 0x8408
table = []
for byte in range(256):
crc = 0
for bit in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
table.append(crc)
return table

table = make_crc_table()

def crc_16_fast(msg):
crc = 0xffff
for byte in msg:
crc = table[(byte ^ crc) & 0xff] ^ (crc >> 8)
return crc ^ 0xffff

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16_fast(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))

如果您愿意,您可以打印该表并将其粘贴到您的脚本中,这样您就不必在每次运行脚本时都计算该表。

关于python - 如何使用 Python 计算此 CRC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53358646/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com