5

我使用 iText 将 xhtml 转换为 pdf。之后,我正在构建生成的 pdf 的 md5 校验和,以仅存储新的/更改的文件。

每个创建的文件都包含一个看起来像哈希的 PdfID0 和 PdfID1。

这些“哈希”是做什么用的?我怎样才能删除它们?

我使用 iText 包中的以下代码来更改元信息:

        com.lowagie.text.pdf.PdfReader reader = new PdfReader(pdfPath);

        com.lowagie.text.pdf.PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempFile));
        HashMap<String, String> hMap = reader.getInfo();          
        hMap.put("Title", "MyTitle");
        hMap.put("Subject", "Subject");
        hMap.put("Keywords", "Key, words, here");
        hMap.put("Creator", "me");
        hMap.put("Author", "me");
        hMap.put("Producer", "me");
        hMap.put("CreationDate", null);
        hMap.put("ModDate", null);
        hMap.put("DocChecksum", null);

        stamper.setMoreInfo(hMap);
        stamper.close(); 

以及使用 pdftk 提取的文件元数据:

InfoKey: Creator
InfoValue: me
InfoKey: Title
InfoValue: MyTitle
InfoKey: Author
InfoValue: me
InfoKey: Producer
InfoValue: me
InfoKey: Keywords
InfoValue: Key, words, here
InfoKey: Subject
InfoValue: Subject
PdfID0: 28c71a8d7790a4d3e85ce879a90dec0
PdfID1: 4c5865d36c7a381e6166d5e362d0aafc
NumberOfPages: 1

感谢您的任何提示

4

2 回答 2

7

您看到标记为PdfID0PdfID1的元数据转储是相应 PDF 文件末尾的pdftk以下 PDF 代码的一部分(示例):trailer

trailer
   << /Size 32
      /Root 24 R
      /Info 19 R
      /ID [ 
            <28c71a8d7790a4d3e85ce879a90dec0>
            <4c5865d36c7a381e6166d5e362d0aafc>
          ]
   >> startxref
81799
%%EOF

/ID只有存在条目时才需要预告片字典中的条目Encrypt;否则它是一个可选的键。

PDF规范将其描述为:

“一个由两个字节串组成的数组,构成文件的文件标识符(参见第 14.4 节,“文件标识符”)。如果有一个加密条目,这个数组和两个字节串应该是直接对象,并且应该是未加密的。

此外:

“第一个字节字符串应是基于文件最初创建时的内容的永久标识符,并且在文件增量更新时不应更改。第二个字节字符串应是基于文件内容的更改标识符上次更新的时间。第一次写入文件时,两个标识符应设置为相同的值。如果在解析文件引用时两个标识符匹配,则很可能已找到正确且未更改的文件。如果只有第一个标识符匹配,已找到正确文件的不同版本。”

而且它不一定hash 。这是 ISO PDF 规范所建议的(不是“规定”):

“为了帮助确保文件标识符的唯一性,它们应该通过消息摘要算法来计算,例如 MD5(在 Internet RFC 1321 中描述,MD5 消息摘要算法;请参阅参考书目),使用以下信息:

  • 当前时间
  • 文件位置的字符串表示,通常是路径名
  • 文件的大小(以字节为单位)
  • 文件的文档信息字典中所有条目的值(参见 14.3.3,“文档信息字典”)

生成的 PDF 文件中还有一些点可能会随着每次新运行而改变。文档信息字典中的这些键(/Info预告片中引用的条目)

  • /CreationDate
  • /ModDate

可能会在您每次创建或修改 PDF 时更新。

因此,在生成的 PDF 上使用您自己的 MD5 校验和来检查新/更改的文件将不起作用,除非您确保在创建 MD5 哈希之前至少“规范化”/CreationDate/ModDate以及条目。/ID


更新:正如用户mkl在对此答案的评论中正确指出的那样,字典的/CreationDate/ModDate/Info(以及/ID信息)通常具有包含在 PDF 中嵌入的 XML 元数据中的等效信息。pdfinfo您可以在实用程序的帮助下显示完整的 XML 元数据,如下所示:

pdfinfo -meta your.pdf
于 2012-11-02T13:01:18.070 回答
1

关于标识符...... pdf规范说:

文件标识符应由 PDF 文件尾部字典中的可选 ID 条目定义(参见 7.5.5,“文件尾部”)。ID 条目是可选的,但应该使用。该条目的值应为两个字节字符串的数组。第一个字节字符串应是基于文件最初创建时的内容的永久标识符,并且在文件增量更新时不应更改。第二个字节串应是根据文件最后更新时的内容而变化的标识符。首次写入文件时,应将两个标识符设置为相同的值。如果在解析文件引用时两个标识符匹配,则很可能已找到正确且未更改的文件。如果只有第一个标识符匹配,则已找到正确文件的不同版本。

这一点,标识符是可选的,但建议使用。

IText 自动插入和更新标识符。您当然可以更改 iText(毕竟它是开源的)以不这样做。

于 2012-11-02T13:05:53.230 回答