我有以下框架:
7e 01 00 00 01 00 18 ef 00 00 00 b5 20 c1 05 10 02 71 2e 1a c2 05 10 01 71 00 6e 87 02 00 01 42 71 2e 1a 01 96 27 be 27 54 17 3d b9 93 ac 7e
如果我理解正确的话,那就是计算FCS的帧的这一部分:
010000010018ef000000b520c1051002712e1ac205100171006e8702000142712e1a019627be2754173db9
我已尝试将其输入多个在线计算器,但我无法从上述数据中生成0x93ac。
输入类型为十六进制的http://www.lammertbies.nl/comm/info/crc-calculation.html。
0x93ac是如何到达的?
谢谢,
百里
答案 0 :(得分:8)
回答那些在寻找建议时来到这里的人。
关键是密切相关的ITU-T建议中的几点(例如Q.921,已在网上提供了很长时间)说:
这种遗留行为与日常生活惯例相反,其中最高位数字首先按读取顺序写入,并且所有通用在线计算器和库使用常规顺序执行计算并提供可选设置以促进逆转一。 因此,您必须询问在线计算器
相当合理的是,有些计算器只为两者提供了一个共同的设置。
这就是设置"反向数据字节"和#34;在最终XOR"之前反转CRC结果在上一个答案中推荐;
位反转是" xor by 0xffff的另一个名称......"。在将CRC计算结果作为消息FCS(消息的最后两个字节,在您的示例中为' 93 ac')发送之前,有一个目的是对CRC计算结果进行位反转。 详见第4点。
这就是设置"最终值ffff",其名称相当误导,因为它实际上定义了与计算结果相关的模式。由于几种CRC类型需要这样的操作,因此只有xor模式从0(无操作)到0xfff ...(完全反转)不等,通用计算器/库提供简化使用。
这就是点"初始值ffff"。
这背后有一些聪明的想法:
CRC算法的固有属性是
CRC(x.CRC(x))
始终为0(x表示原始邮件,"。"表示连接)。
通过计算而不是运行完整的消息 仅计算消息本身并与FCS进行比较 单独接收意味着更简单的算法(甚至电路) 在接收方。
很容易造成编码错误导致结果变为0.幸运的是,多亏了CRC算法的内在属性,
CRC(x。(CRC(x))')
产生一个独立于x且不等于0的常数值(至少对于CRC-CCITT,我们在这里讨论)。 "'" sign表示第2点所要求的位反转。
答案 1 :(得分:4)
首先,CRC值为0xac93
使用此计算器:http://www.zorc.breitbandkatze.de/crc.html
ffff
ffff
输入您的序列:
%01%00%00%01%00%18%ef%00%00%00%b5%20%c1%05%10%02%71%2e%1a%c2%05%10%01%71%00%6e%87%02%00%01%42%71%2e%1a%01%96%27%be%27%54%17%3d%b9
0xAC93
答案 2 :(得分:0)
这是用于HDLC CRC计算的简单Python脚本。您可以将其用于DLMS
def byte_mirror(c):
c = (c & 0xF0) >> 4 | (c & 0x0F) << 4
c = (c & 0xCC) >> 2 | (c & 0x33) << 2
c = (c & 0xAA) >> 1 | (c & 0x55) << 1
return c
CRC_INIT=0xffff
POLYNOMIAL=0x1021
DATA_VALUE=0xA0
SNRM_request=[ 0x7E, 0xA0, 0x08, 0x03, 0x02, 0xFF, 0x93, 0xCA, 0xE4, 0x7E]
print("sent>>", end=" ")
for x in SNRM_request:
if x>15:
print(hex(x), end=" ")
else:
a=str(hex(x))
a = a[:2] + "0" + a[2:]
print(a, end=" ")
lenn=len(SNRM_request)
print(" ")
crc = CRC_INIT
for i in range(lenn):
if( (i!=0) and (i!=(lenn-1)) and (i!=(lenn-2)) and (i!=(lenn-3)) ):
print("i>>",i)
c=SNRM_request[i]
c=byte_mirror(c)
c = c << 8
print(hex(c))
for j in range(8):
print(hex(c))
print("CRC",hex(crc))
if (crc ^ c) & 0x8000:
crc = (crc << 1) ^ POLYNOMIAL
else:
crc = crc << 1
c = c << 1
crc=crc%65536
c =c%65536
print("CRC-CALC",hex(crc))
crc=0xFFFF-crc
print("CRC- NOT",hex(crc))
crc_HI=crc//256
crc_LO=crc%256
print("CRC-HI",hex(crc_HI))
print("CRC-LO",hex(crc_LO))
crc_HI=byte_mirror(crc_HI)
crc_LO=byte_mirror(crc_LO)
print("CRC-HI-zrc",hex(crc_HI))
print("CRC-LO-zrc",hex(crc_LO))
crc=256*crc_HI+crc_LO
print("CRC-END",hex(crc))