似乎与获得确定性的哈希值的POI XLSX格式,消息摘要SHA-256实现的问题,即使是空的ByteArray流。这种情况在数百次甚至数千次迭代之后随机发生。与POI消息摘要XSSF/XLSX散列非决定论SHA-256
用于重现该问题的相关代码片段:
// 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");
}
引用的散列器和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格式似乎不受Pro瑕疵描述。 没有任何人有一个线索,这可能是造成这一点,如果不是一个错误的POI本身?基本上,上面的代码是指 https://poi.apache.org/spreadsheet/examples.htmlBusinessPlan example
感谢您的输入!
感谢您对此的看法。我将不得不测试和写入实际的文件来重新检查它。但是不应该设置CoreProperty元数据(创建和修改时间,如上所述)来防止这种情况发生?或者它只影响内部元数据,而不影响档案的内容? – fozzybear
我认为最好的方法来检查这将是你说的:写文件,并检查邮编内容。在我现有的文件中,我没有修改CoreProterties,所以我不能确定这是什么原因导致我的情况有所不同。 –
看起来你已经把我放在了正确的轨道上,piet!我已经提取了生成的预期和实际内容,并且所有内容都是相似的,文件,文件夹,CRC,但修改时间相差2秒。鉴于事实,我明确告诉POI清除修改时间,这很奇怪。除非这会影响其他内部修改时间。现在我只需要弄清楚,在创建之前或之后如何处理XLSX内部文件的修改时间。否则,我看不到其他方式,但要解压缩,触摸并重新压缩文件。你怎么看? – fozzybear