我正在从头开始设计二进制文件格式,我想在开头包含一些魔术字节,以便可以轻松识别它。我该如何选择哪些字节?我不知道任何魔数的中央注册表,所以它只是挑选一些相当随机的东西,例如附近的 UNIX 机器上的文件命令尚未识别的问题吗?
2 回答
远离超短幻数。仅仅因为您正在设计二进制格式并不意味着您不能使用文本字符串作为标识符。紧随其后的是 EOF 字符,作为额外的奖励,那些cat或键入二进制文件的人不会得到一个损坏的终端。
没有普遍正确的方法。可以建议最佳实践,但这些通常是根据情况而定的。例如,如果您正在检查易失性存储器的完整性,该存储器在通电时具有未定义的初始状态,那么将许多 0 或 1 合并到一个序列(即FFF0 00FF F000
)中可能是有益的,这可以在随机噪声中脱颖而出。
如果文件主要是二进制文件,一个流行的选择是使用像 ASCII 这样的文本编码,它在十六进制编辑器中的二进制数据中脱颖而出。例如,GIF 使用GIF89a
,FLAC 使用fLaC
. 另一方面,在随机文本文件中可能会错误地检测到纯文本标识符,因此可能会包含无效/控制字符。
一般来说,它们是什么并不重要,即使是一堆 NULL 字节也可以用于文件检测。但理想情况下,您需要最长的唯一标识符,并且至少 4 个字节长。任何小于 4 字节的标识符都会更频繁地出现在随机数据中。时间越长,它被检测为误报的可能性就越小。一些已知的示例长达 40 个字节。在某种程度上,它就像一个密码。
此外,它不必位于偏移量 0 处。文件签名通常在偏移量为零,因为如果首先处理它,则首先存储它是有意义的。
也就是说,单个文件签名不应该是唯一的防线。即使签名匹配,实际的解析过程本身也应该能够验证完整性并清除无效文件。这可以通过附加文件签名、使用长度敏感数据、值/范围检查,尤其是哈希/校验和值来完成。