Hash 出于完整性目的对文本文件进行哈希

Hash 出于完整性目的对文本文件进行哈希,hash,line-endings,Hash,Line Endings,我有一个更一般的要求,即跟踪提交到源代码中并部署在二进制文件中的资产文件中的更改,但目前我正在单元测试环境中实现它,并面临未来的潜在问题。在提出TLDR问题之前,我将展示大量上下文信息 场景 一些应用程序资产是通过ClasspathResource[1]从提交到Git存储库的CSV文件加载的,它们有时可能会更改。更改跨提交发生,但对于运行时应用程序,更改跨应用程序的不同版本发生 我的测试解决方案 我已经实现了以下机制来提醒我资源中的更改: @Before public void setUp()

我有一个更一般的要求,即跟踪提交到源代码中并部署在二进制文件中的资产文件中的更改,但目前我正在单元测试环境中实现它,并面临未来的潜在问题。在提出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 box上运行测试,工作得非常出色。切换到Linux,我发现它们失败了。我立刻意识到这可能是因为我完全忘记了行的结尾

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

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

TL;博士 给定一个文本文件,我可以提取和存储它的任何散列(不仅仅是加密的,我使用了MD5),我如何判断它已经改变了,而不考虑文件处理的环境,这可能会修改行尾

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


[1] Spring framework工具包装
类。getResourceAsStream

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


例如,计算
md5sum | dos2unix文件
,并在代码中使用适当的
,以动态规范文件

,即使我回答了自己的问题,我仍然担心可能影响文件二进制有效负载的其他因素,即使文本内容没有更改。在许多情况下,MS只接受
LF
以及
CRLF
。我的经验是,您应该标准化LF结尾。大多数Windows工具只处理LF结尾。Linux工具往往在CRLF结尾处阻塞。通过像
dos2unix
这样的转换过滤器运行东西只会浪费处理器资源,而且会在某个时候咬到你。