【问题标题】:Hash of a textual file for integrity purposes出于完整性目的对文本文件进行哈希处理
【发布时间】:2018-07-05 12:21:11
【问题描述】:

我有一个更一般的要求来跟踪提交到源代码并部署在二进制文件中的资产文件的更改,但现在我在单元测试环境中实现它并且面临未来的潜在问题。在问 TLDR 问题之前,我会展示很多上下文信息。

场景

一些应用程序资产是从通过ClasspathResource[1] 提交到 Git 存储库的 CSV 文件加载的,它们有时可能会更改。更改发生在提交之间,但对于运行时应用程序,更改发生在应用程序的不同版本中。

我的测试解决方案

我已经实施了以下机制来提醒我资源的变化:

@Before
public void setUp() throws Exception
{
    assertEquals("Resource file has changed. Make sure the test reflects the changes in the file and update the checksum", MD5_OF_FILE,
                 DigestUtils.md5Hex(new ClassPathResource("META-INF/resources/assets.csv").getInputStream()));
 
}

基本上,我希望我的单元测试失败,直到我明确编码文件的校验和。当我运行 md5sum assets.txt 时,我将结果硬编码到代码中,以便测试知道它们正在使用文件的固定版本。

问题

我在我自己的 Windows 机器上运行了测试,并且工作得很好。切换到Linux,我发现他们失败了。我立刻意识到这可能是由于行尾,我完全忘记了。

在特定情况下,Git 被配置为提交文件LF 但签出(在 Windows 中)CRLF。此配置对于使用源代码是合理的。

所以我需要检查资产文件是否以智能方式更改,允许框更改/重新解释行尾。对于将存储文件哈希并比较实际资产文件(可能已更改)的运行时应用程序尤其如此,对差异执行纠正措施 ==> 重新加载资产。

TL;DR

给定一个文本文件,我可以从中提取和存储任何散列(不仅仅是加密,我使用了 MD5),我怎么知道它已经改变了不管文件处理的环境, 可能修改行尾?

注意 我要求不要在资产本身中使用版本控制系统(例如,第一行有增量版本,因为开发人员将无法正确更新)。

[1] Spring框架工具包装Class.getResourceAsStream

【问题讨论】:

  • 尽管我已经回答了我自己的问题,但我仍然担心其他因素可能会影响文件的二进制有效负载,即使文本内容不变
  • 在许多情况下,MS 只接受 LFCRLF
  • 我的经验是你应该标准化 LF 结尾。大多数 Windows 工具只处理 LF 结尾。 Linux 工具往往会因 CRLF 结尾而窒息。通过dos2unix 之类的转换过滤器运行东西只是浪费处理器资源,并且会在某些时候咬你。

标签: hash line-endings


【解决方案1】:

解决方案可以将文件规范化为选定的行结尾,即始终 CRLF 或始终 LF,然后计算该规范化内容的加密哈希。

例如计算 md5sum | dos2unix file 并在代码中使用适当的 Stream 来规范化文件

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多