似乎與獲得確定性的哈希值的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