8位二进制加法
有人能解释一下如何用8位二进制加法计算校验和吗?这是文档的摘录:
这是消息的一般形式:
STX | TYPE | FS | DATA | FS | CHK | ETX
STX 是十六进制 02
ETX 是十六进制 03
FS 是十六进制 15
“类型”是唯一的 1 字节消息标识符(例如,“P”表示轮询)信息)。 “数据”包含可打印的 ASCII 字符。
校验和 校验
和是根据
和
。 校验和是通过将所有包含的字符进行 8 位二进制加法计算得出的,其中第 8 位或奇偶校验位假定为零。超过第 8 位的进位将丢失。8 位结果被转换为两个可打印的 ASCII 十六进制字符,范围从 00 到 FF,然后作为
字符。 CHK>
) 或否定确认 (
) 的基础。
Can someone explain how to calculate checksum with 8-bit binary addition? This is an excerpt from the documentation:
This is the general form of the messages:
STX | TYPE | FS | DATA | FS | CHK | ETX
STX is HEX 02
ETX is HEX 03
FS is HEX 15
The "type" is a unique, 1-byte message identifier (e.g., 'P' for Poll message).
"Data" contains printable ASCII characters.
Checksum
The Checksum is computed on all characters, including all the <FS>
characters, between <STX>
and <CHK>
. The Checksum is calculated by the 8-bit binary addition of all included characters with the 8th or parity bit assumed to be zero. Carries beyond the 8th bit are lost. The 8-bit result is converted into two printable ASCII Hex characters, ranging from 00 to FF, which are then inserted into the data stream as <CHK>
. The Hex characters A-F are uppercase. The receiving device recalculates the checksum on the buffered message and compares it with the checksum it received. The comparison is the basis for subsequent acknowledgement (<ACK>
) or negative acknowledgement (<NAK>
) of the transmission.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
将每个字符视为整数值。由于每个字符的高位假设为零(正如规范中没有说你需要检查它),用这样的东西掩盖它的值(伪C / C ++ / Java /任何):
现在只需执行加法(伪 C/C++/Java/其他):
这将连续添加每个 ASCII 字符,并从结果总和中删除第 8 位之后的所有内容。当你全部完成时(C 或写得很糟糕的 C++):
作为一种优化(如果你真的需要它 - 在这种情况下不太可能!)你可以推迟
s &= 0xff
位并相反,在使用校验和时使用截断。然而,这不会为您节省太多性能——您的 I/O 将会更加昂贵——并且可能会导致您在稍后重构代码时忘记这样做。Treat each character as an integer value. Since each character's high bit is assumed to be zero (as in the spec doesn't say you need to check it), mask its value with something like this (pseudo-C/C++/Java/whatever):
Now you just do the add (pseudo-C/C++/Java/whatever):
This will consecutively add each ASCII character and remove everything past the 8th bit from the resulting sum. When you're all finished (C or badly-written C++):
As an optimization (if you really need it -- unlikely in this case!) you can defer the
s &= 0xff
bit and instead use the truncation at the point of use for the checksum. This won't save you much on performance, however -- your I/O will be far more expensive -- and leads to the possibility of you forgetting to do it at some later date when you refactor your code.如需添加,请使用以下函数。
对于旧版本的 Delphi,没有“for in”:
函数 Summatory 被声明为 Byte,因此它将“忽略”超出第 8 位的进位。您可以传递要添加的所有字节。
使用
SysUtils
中的函数IntToHex
将 8 位结果转换为两个可打印的 ASCII 十六进制字符。例如:
ChkSum := IntToHex(Summatory(Data), 2);
For addition, use the following function.
For older versions of Delphi, with no "for in":
The function Summatory is declared as Byte, so it will "ignore" carries beyond the 8th bit. You can pass all of the bytes that you want to add.
Use the function
IntToHex
fromSysUtils
to converted the 8-bit result into two printable ASCII Hex characters.Ex:
ChkSum := IntToHex(Summatory(Data), 2);
在 Java 中,您可以执行以下操作。
In Java you can do the following.
当字节总和超过 256 时,上述答案都不起作用。OP
可能试图将 Siemens Dimension EXL200 化学分析仪与其 _Lab 信息连接起来系统。
他发布的段落(关于校验和的规范)是从他们的手册中复制/粘贴的。
在过去的 12 个小时里,我一直在努力解决这个特殊问题,但找不到任何解决方法。
我包括了西门子手册中提到的一些字符串,因为它们提供了校验和。
您会注意到上面的所有答案都有效,但仅适用于某些字符串。
在其他情况下,手册中的校验和与我们使用上面发布的方法得到的完全不同。
我发布了两个例子,1个失败,1个成功=>相同的算法。
为了方便起见(由于协议使用十六进制字符,我包含了实际的字节数组,以便任何阅读本文的人都可以用他/她选择的语言进行尝试)。
我希望有人可以在这里找到解决方案:
鉴于上面的示例,我注意到它似乎在总和后就失败了字节数跨越某个值(我不能确定),但我认为它大约是 256。任何高于 256 的值都会得到与西门子人员似乎想要的不同的结果。
第一个示例大幅超过了 256,但第二个示例达到了 226。手册中还有一个字节和更小的示例,我们上面的代码似乎可以工作,生成预期的校验和。
我不是一个很好的程序员,但我确信这与溢出有关。
巴尔加夫·R.
None of the answers above work, when the sum of the bytes crosses 256.
The OP was probably trying to interface a Siemens Dimension EXL200 chemistry analyzer with his _Lab information system.
The paragraph he's posted (about the spec for the checksum) is copy/paste from their manual.
I've been banging my head against this particular problem for the last 12 hours and cannot find any way around it.
I am including some of the strings mentioned in the Siemens Manual, as they have provided the checksums.
You will notice that all the answers above work, but only for some of the strings.
In others, the checksum in the manual is completely different from what we get by using the methods posted above.
I am posting two examples, 1 failure, and 1 success => same algorithm.
For convenience(as the protocol uses HEX characters, I'm including the actual byte arrays, so that anyone reading this can try it in his/her language of choice).
I hope someone can find a solution here:
Given the above examples, I've noticed that it seems to fail as soon as the sum of the bytes crosses a certain value(what I cannot be sure), but I think its around 256. Anything above 256 gives a result different from whatever the people at Siemens seem to want.
The first example has crossed 256 by a big margin, but the second one is at 226. There is another example in the manual of an even smaller byte sum, where our code above seems to work, producing the expected checksum.
I'm not a very good programmer, but I'm sure this has something to do with overflows.
Bhargav R.
这个(未经测试的)类似 JavaScript 的函数可以解决您的问题吗?
Does this (untested) JavaScript-like function solve your problem?