Es scheint ein Problem mit deterministischen Hash-Werte für das POI XLSX-Format mit MessageDigest SHA-256-Implementierung, auch für leere ByteArray-Streams. Dies geschieht zufällig nach mehreren hundert oder sogar nur tausenden von Iterationen.POI XSSF/XLSX Hash-Indeterminismus mit MessageDigest SHA-256
Der entsprechende Code-Schnipsel verwendet, um das Problem zu reproduzieren:
// 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");
}
referenzierten Hasher und POI-Code:
// 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);
}
Versuchte indeterminism aufgrund Meta-Daten wie Erstellungszeit zu eliminieren, ohne Erfolg:
// 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;
}
Das HSSF/XLS-Format scheint nicht von dem Profi betroffen zu sein beschämt beschrieben. Hat jemand eine Ahnung, was könnte das verursachen, wenn nicht ein Fehler in POI selbst? Grundsätzlich bezieht sich der obige Code auf https://poi.apache.org/spreadsheet/examples.htmlBusinessPlan example
Vielen Dank für Ihre Eingabe! docx und xlsx Dateiformate sind im Grunde eine Reihe von Reißverschluss-up xml-Dateien
:
Danke für Ihre Gedanken dazu. Ich muss die tatsächlichen Dateien testen und schreiben, um sie zu überprüfen. Aber sollte das Setzen der CoreProperty-Metadaten (wie oben beschrieben) nicht eine Situation wie diese verhindern? Oder betrifft das nur interne Metadaten, nicht die des Archivs? – fozzybear
Ich denke, der beste Weg, dies zu überprüfen, wäre wie gesagt: schreibe die Datei und überprüfe die ZIP-Inhalte. In meinen vorhandenen Dateien hatte ich die CoreProterties nicht verändert, daher kann ich nicht sagen, ob das in meinem Fall den Unterschied verursacht. –
Sieht aus, als hättest du mich auf den richtigen Weg gebracht, Piet! Ich habe die generierten erwarteten und tatsächlichen Inhalte extrahiert, und alles war ähnlich, Dateien, Ordner, CRCs, aber die Änderungszeiten unterschieden sich um 2 Sekunden. Angesichts der Tatsache, dass ich POI ausdrücklich gesagt habe, die Modifizierungszeiten zu löschen, ist das merkwürdig. Es sei denn, dies wirkt sich auf andere interne Modifikationszeiten aus. Jetzt muss ich nur herausfinden, wie man die Änderungszeiten der Dateien innerhalb des XLSX vor oder nach der Erstellung manipuliert. Ansonsten sehe ich keinen anderen Weg, als die Dateien zu entpacken, zu berühren und neu zu zippen. Was denken Sie? – fozzybear