빈 ByteArray 스트림에 대해서도 MessageDigest SHA-256 구현으로 POI XLSX 형식에 대한 결정적인 해시 값을 얻는 데 문제가있는 것 같습니다. 이것은 수백 또는 수천 번의 반복 작업 후에 임의로 발생합니다. 문제를 재현하는 데MessageDigest와 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 형식은 프로에 영향을받지 않는 것으로 보입니다. blem 설명. POI 자체의 버그가 아니라면 원인을 알 수있는 단서가 있습니까? 기본적으로 위 코드는 다음을 말합니다. https://poi.apache.org/spreadsheet/examples.htmlBusinessPlan example
감사합니다.
의견을 보내 주셔서 감사합니다. 나는 실제 파일을 테스트하고 쓰고 그것을 두 번 체크해야 할 것이다. 그러나 CoreProperty 메타 데이터 (위와 같이 작성 및 수정 시간)를 설정하면 안됩니다. 이와 같은 상황을 방지 할 수 있습니까? 또는 아카이브의 메타 데이터가 아닌 내부 메타 데이터에만 영향을 줍니까? – fozzybear
나는 이것을 확인하는 가장 좋은 방법은 당신이 말한 것처럼 될 것이라고 생각한다 : 파일을 작성하고 우편 번호를 확인한다. 기존 파일에서 CoreProterties를 수정하지 않았으므로 그것이 내 경우에 차이를 일으키는 지 여부를 알 수 없습니다. –
나를 옳은 길에 태운 것처럼 보입니다, piet! 생성 된 예상 내용과 실제 내용을 추출했으며 파일, 폴더, CRC는 모두 유사했지만 수정 시간은 2 초 차이가있었습니다. 사실, 내가 수정 시간을 명확히하기 위해 POI에 명시 적으로 말했지만, 이것은 이상합니다. 그렇지 않으면 다른 내부 수정 시간에 영향을 미치지 않습니다. 이제는 XLSX 내부 또는 이전에 생성 된 파일의 수정 시간을 조작하는 방법을 알아야합니다. 그렇지 않으면 다른 방법은 없지만 압축을 풀고 파일을 터치하고 다시 압축합니다. 어떻게 생각해? – fozzybear