gpt4 book ai didi

java - 更改 PDF 然后删除更改时,恢复的文件和原始文件的哈希值不同

转载 作者:行者123 更新时间:2023-12-01 12:19:46 24 4
gpt4 key购买 nike

如果我访问 PDF 以使用代码在自定义属性中添加某些内容 文件 src_2 = 新文件(embed_source); 文件 dest_2 = 新文件(embed_destination_2);

                    try {
FileUtils.copyFile(src_2, dest_2);
} catch (IOException e) {
e.printStackTrace();
}
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
Map<String, String> info = reader.getInfo();
System.out.println(info.get("Lala"));

stamper.setMoreInfo((HashMap<String, String>) info);
stamper.close();
reader.close();
}

我没有更改 src 文件的任何内容,我所做的只是获取有关 src 文件的一些信息。但是,在运行程序之前和之后,我从 src 文件中得到了 2 个不同的哈希结果。我可以知道为什么吗?

最佳答案

如果您阅读过 ISO-32000-1,您应该知道没有两个 PDF 在设计上是相等的。两个 PDF 之间最典型的差异之一是 ID:

来自 ISO-32000-1:

ID: An array of two byte-strings constituting a file identifier.

来自第 14.4 节,标题为“文件标识符”:

The value of this entry shall be an array of two byte strings. The first byte string shall be a permanent identifier based on the contents of the file at the time it was originally created and shall not change when the file is incrementally updated. The second byte string shall be a changing identifier based on the file’s contents at the time it was last updated. When a file is first written, both identifiers shall be set to the same value. If both identifiers match when a file reference is resolved, it is very likely that the correct and unchanged file has been found. If only the first identifier matches, a different version of the correct file has been found.

如果您从头开始创建 PDF,则 ID 由两个相同的标识符组成。当您更新 PDF 以添加某些内容时,第一个 ID 会被保留,第二个 ID 会被更改。如果您更新 PDF 以删除该内容,则第二个 ID 会再次更改,但根据定义,它不应与第一个 ID 相同,因为您处于工作流程的不同部分。

注意:创建标识符相同的 PDF 的工具并不多。这是因为从头开始创建的 PDF 通常在最终版本保存到磁盘之前进行操作。只需使用 Adob​​e Acrobat 创建 PDF 即可重现此内容:您会注意到标识符对由两个不同的值组成。这使得询问:我们能否创建一个使第二个标识符与第一个标识符相同的情况?

此外:PDF 固有的特点是对象的组织方式是随机的。您使用哈希的用例违反了 PDF 标准。

如何解决这个问题?

您就是提出问题[如何] Add / delete / retrieve information from a PDF using a custom property 的人。

在回答这个问题时,我解释了如何将元数据添加到现有 PDF:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));

这将创建一个新的 PDF 文件,其中的对象将被重新排序。

但是,您可以将此行更改为:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true);

现在您正在创建 PDF 文件的增量更新

什么是增量更新?

假设您的原始 PDF 文件如下所示:

%PDF-1.4
% plenty of PDF objects and PDF syntax
%%EOF

当您使用 iText 操作此类文件时,您会得到一个更改的 PDF 文件:

%PDF-1.4
% plenty of altered PDF objects and altered PDF syntax
%%EOF

在此过程中,对象可以重新编号、重新组织等...如果您第一次添加一些内容,第二次删除一些内容,您可以预期 PDF 在打开时对于人眼来说看起来是一样的PDF 查看器中的文档,但您不应期望 PDF 语法相同。这种假设表明我们完全缺乏对 PDF 格式的洞察力。

但是,当您在附加模式下使用PdfStamper执行增量更新时,您将获得增量更新的PDF:

%PDF-1.4
% plenty of PDF objects and PDF syntax
%%EOF
% updates for PDF objects and PDF syntax
%%EOF

在这种情况下,原始 PDF 的原始字节不会更改。文件大小变得更大,因为您现在将拥有一些冗余信息(某些对象将不再使用,某些对象将拥有旧版本和新版本),但使用增量更新的优点是您可以随时返回原始文件。

搜索倒数第二个出现的 %%EOF 并删除后面的所有字节就足够了,您将获得一个截断的 PDF 文件:

%PDF-1.4
% plenty of PDF objects and PDF syntax
%%EOF

您现在可以获取此截断的 PDF 文件的哈希值,并将其与原始 PDF 文件的哈希值进行比较。这些哈希值将是相同的。

警告:请注意 %%EOF 后面的空白字符。它们可能会在字节级别造成最小的差异,从而导致哈希值不同。

关于java - 更改 PDF 然后删除更改时,恢复的文件和原始文件的哈希值不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26773266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com