java-使用MessageDigest SHA-256的POI XSSF / XLSX哈希不确定性
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-使用MessageDigest SHA-256的POI XSSF / XLSX哈希不确定性,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3248字,纯文字阅读大概需要5分钟。
内容图文
![java-使用MessageDigest SHA-256的POI XSSF / XLSX哈希不确定性](/upload/InfoBanner/zyjiaocheng/665/a54c765dd37b47c8abcd2e2f6692aed9.jpg)
使用MessageDigest SHA-256实现获取POI XLSX格式的确定性哈希值似乎存在问题,即使对于空的ByteArray流也是如此.在数百次甚至数千次迭代之后,这是随机发生的.
用于重现该问题的相关代码段:
// TestNG FileTest:
@Test(enabled = true) // indeterminism at random iterations, such as 400 or 1290
public void emptyXLSXTest() throws IOException, NoSuchAlgorithmException {
final Hasher hasher = new HasherImpl();
boolean differentSHA256Hash = false;
for (int i = 0; i < 10000; i++) {
final ByteArrayOutputStream excelAdHoc1 = BusinessPlanInMemory.getEmptyExcel("xlsx");
final ByteArrayOutputStream excelAdHoc2 = BusinessPlanInMemory.getEmptyExcel("xlsx");
byte[] expectedByteArray = excelAdHoc1.toByteArray();
String expectedSha256 = hasher.sha256(expectedByteArray);
byte[] actualByteArray = excelAdHoc2.toByteArray();
String actualSha256 = hasher.sha256(actualByteArray);
if (!expectedSha256.equals(actualSha256)) {
differentSHA256Hash = true;
System.out.println("ITERATION: " + i);
System.out.println("EXPECTED HASH: " + expectedSha256);
System.out.println("ACTUAL HASH: " + actualSha256);
break;
}
}
Assert.assertTrue(differentSHA256Hash, "Indeterminism did not occur");
}
引用的Hasher和POI代码:
// HasherImpl class:
public String sha256(final InputStream stream) throws IOException, NoSuchAlgorithmException {
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
final byte[] bytesBuffer = new byte[300000];
int bytesRead = -1;
while ((bytesRead = stream.read(bytesBuffer)) != -1) {
digest.update(bytesBuffer, 0, bytesRead);
}
final byte[] hashedBytes = digest.digest();
return bytesToHex(hashedBytes);
}
试图消除由于元数据(例如创建时间)而导致的不确定性,但无济于事:
// POI BusinessPlanInMemory helper class:
public static ByteArrayOutputStream getEmptyExcel(final String fileextension) throws IOException {
Workbook wb;
if (fileextension.equals("xls")) {
wb = new HSSFWorkbook();
}
else {
wb = new XSSFWorkbook();
final POIXMLProperties props = ((XSSFWorkbook) wb).getProperties();
final POIXMLProperties.CoreProperties coreProp = props.getCoreProperties();
coreProp.setCreated("");
coreProp.setIdentifier("1");
coreProp.setModified("");
}
wb.createSheet();
final ByteArrayOutputStream excelStream = new ByteArrayOutputStream();
wb.write(excelStream);
wb.close();
return excelStream;
}
HSSF / XLS格式似乎不受所描述问题的影响.
是否有人知道,如果不是POI本身的错误,可能是什么原因导致的?基本上,上面的代码是指
https://poi.apache.org/spreadsheet/examples.htmlBusinessPlan example
感谢您的输入!
解决方法:
这不是一个明确的答案,但是我怀疑会发生什么:
docx和xlsx文件格式基本上是一堆压缩的xml文件.将它们重命名为.zip并使用您喜欢的zip工具打开时,很容易看到.
在检查由word创建的文件时,我注意到存档中包含的所有文件的更改时间戳始终为1980-01-01 00:00:00,而在使用POI创建的文件中,它将显示文件的实际时间戳.
所以我怀疑您的问题是在excelAdHoc1和excelAdHoc2中的一个或多个文件之间存在时间戳差异时发生的.当创建一个或另一个文件时时钟切换到下一秒时,可能会发生这种情况.
这不会影响XLS文件,因为HSSF格式不是“ zip xml”类型,因此不包含任何可能具有不同时间戳的嵌套文件.
要在写入文件后更改时间戳,可以尝试使用`java.util.zip“-package.我还没有测试过,但这应该可以解决问题:
ZipFile file = new ZipFile(pathToFile);
Enumeration<ZipEntry> e = file.entries();
while(e.hasMoreElements()) {
ZipEntry entry = e.nextElement();
entry.setTime(0L);
}
内容总结
以上是互联网集市为您收集整理的java-使用MessageDigest SHA-256的POI XSSF / XLSX哈希不确定性全部内容,希望文章能够帮你解决java-使用MessageDigest SHA-256的POI XSSF / XLSX哈希不确定性所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。