How the IO-Link IODD checksum works

How the IO-Link IODD checksum works

IO-Link IODD 校验和是如何工作的

Every IODD (IO Device Description) file carries a checksum near the end: <Stamp crc="1462814215"> <Checker name="IODD-Checker V1.1.1" version="V1.1.1.0"/> </Stamp> It is mandatory. Change one byte anywhere in the file and the stamp no longer matches, and the file will be rejected by engineering tools, by masters, and by the IODDfinder upload process. 每个 IODD(IO 设备描述)文件末尾附近都带有一个校验和:<Stamp crc="1462814215"> <Checker name="IODD-Checker V1.1.1" version="V1.1.1.0"/> </Stamp>。这是强制性的。只要文件中任何位置的一个字节发生改变,校验戳就会失效,文件将被工程工具、主站(Master)以及 IODDfinder 上传流程拒绝。

Despite the IO-Link ecosystem being nearly two decades old, there has been no open-source implementation of this algorithm — the only way to produce a valid stamp was to run the official closed-source, Windows-only IODD-Checker. This post explains exactly how the checksum is computed. 尽管 IO-Link 生态系统已经存在近二十年,但该算法一直没有开源实现——生成有效校验戳的唯一方法是运行官方闭源、仅限 Windows 使用的 IODD-Checker。本文将详细解释该校验和是如何计算的。

The algorithm / 算法

The procedure is defined in IODD Specification 10.012, and the specification text is precise and complete. In summary: 该流程定义在 IODD 规范 10.012 中,规范文本精确且完整。总结如下:

  1. Use CRC-32 as defined in ITU-T V.42 §8.1.1.6.2 / ISO/IEC 13239:2002.
  2. 使用 ITU-T V.42 §8.1.1.6.2 / ISO/IEC 13239:2002 定义的 CRC-32。
  3. Read the file in binary mode.
  4. 以二进制模式读取文件。
  5. Feed bytes into the CRC up to and including the literal string <Stamp crc=".
  6. 将字节输入 CRC 计算,直到并包含字面字符串 <Stamp crc="
  7. Skip the attribute’s digits entirely.
  8. 完全跳过该属性的数字部分。
  9. Resume at the closing " and hash through to end of file.
  10. 从闭合的 " 处恢复,并继续哈希计算直到文件末尾。
  11. If the root element is <ExternalTextDocument>, append the ASCII decimal digits of the main IODD’s CRC.
  12. 如果根元素是 <ExternalTextDocument>,则追加主 IODD 的 CRC 的 ASCII 十进制数字。
  13. The result is an unsigned 32-bit integer, written in decimal.
  14. 结果是一个以十进制书写的无符号 32 位整数。

It’s just zlib CRC-32 / 它就是 zlib CRC-32

The specification’s reference to ITU-T V.42 sounds exotic, but that standard describes the ordinary CRC-32 everyone already has: the same one used by zlib, gzip and PNG. 规范中对 ITU-T V.42 的引用听起来很生僻,但该标准描述的是每个人都已经拥有的普通 CRC-32:即 zlib、gzip 和 PNG 所使用的同一个算法。

The self-reference trick / 自引用技巧

A checksum stored inside the file it protects is a circular definition: writing the value changes the bytes, which changes the value. The standard escape is to zero the field before hashing. IODD instead skips it. 存储在受保护文件内部的校验和是一个循环定义:写入该值会改变字节,进而改变该值。标准的解决方法是在哈希前将该字段置零。而 IODD 采取的方式是跳过它。

“Binary mode” is the important phrase / “二进制模式”是关键

Step 2 is where most independent implementations go wrong, because the deviations are ones a language runtime makes on your behalf. 第 2 步是大多数独立实现出错的地方,因为偏差往往是由语言运行时环境代你做出的。

  • A UTF-8 BOM is part of the content. Many vendor IODDs begin with EF BB BF. Reading the file as text usually strips it silently. Those three bytes are hashed.
  • UTF-8 BOM 是内容的一部分。 许多厂商的 IODD 以 EF BB BF 开头。以文本方式读取文件通常会静默地将其剥离,但那三个字节是参与哈希计算的。
  • Line endings are part of the content. Real IODDs are commonly CRLF. Opening a file in text mode on some platforms, or normalising newlines “for consistency”, changes every line in the document.
  • 换行符是内容的一部分。 实际的 IODD 通常使用 CRLF。在某些平台上以文本模式打开文件,或为了“一致性”而标准化换行符,会改变文档中的每一行。
  • The XML must not be reparsed. Round-tripping through a DOM and reserialising will alter attribute quoting, self-closing tag style, entity escaping, namespace declarations and whitespace — all semantically irrelevant, all fatal to the checksum.
  • XML 不得被重新解析。 通过 DOM 进行往返处理并重新序列化会改变属性引号、自闭合标签样式、实体转义、命名空间声明和空格——这些在语义上无关紧要,但对校验和来说是致命的。

The practical rule is that the CRC is computed over an opaque byte array, not over an XML document. Any tool that edits IODDs must therefore make surgical, byte-preserving modifications rather than parse-and-rewrite ones. 实际的规则是:CRC 是基于不透明的字节数组计算的,而不是基于 XML 文档。因此,任何编辑 IODD 的工具都必须进行外科手术式的、保留字节的修改,而不是解析并重写。

Translation files are chained / 翻译文件是链式的

IODD supports external language documents — separate files with an <ExternalTextDocument> root, holding translations of a device’s UI strings. These get one extra step. After hashing their own bytes to end of file, the decimal digits of the main IODD’s CRC are appended to the stream as ASCII characters. IODD 支持外部语言文档——即带有 <ExternalTextDocument> 根节点的独立文件,用于存放设备 UI 字符串的翻译。这些文件多了一个步骤:在对自身字节哈希到文件末尾后,主 IODD 的 CRC 的十进制数字会作为 ASCII 字符追加到流中。