【问题标题】:removing PDFID in PDF删除 PDF 中的 PDFID
【发布时间】:2012-11-02 10:54:11
【问题描述】:

我使用 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

感谢任何提示

【问题讨论】:

  • 在生成 SHA1 总和时,这些 ID 存在完全相同的问题。您是否知道如何去除/规范化它,或者一旦您知道以下信息就中止了?

标签: java pdf itext


【解决方案1】:

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

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

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

PDF 规范将其描述为:

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

还有:

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

而且它不是必然是哈希。以下是 ISO PDF 规范建议(不是“规定”):

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

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

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

  • /CreationDate
  • /ModDate

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

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


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

pdfinfo -meta your.pdf

【讨论】:

  • 除了那些信息字典条目之外,XML 元数据流中可能还有等效条目。
  • @mkl:感谢您的提示。 (为了简单起见,我最初跳过了这个事实。但我没有考虑到这可能会导致人们构建过于简单的解决方案,从而无法正常工作。)我会相应地更新我的答案。
【解决方案2】:

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

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

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

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

【讨论】:

  • 所以不可能跳过使用可用 iText 版本插入标识符(例如通过属性)?我需要自己修改它吗?
  • 是的。毕竟,在不更改 id 的情况下更改文档是一种不受欢迎的行为。
  • 如果您求助于更改 iText,请记住,pdf 中还有许多其他条目至少取决于上次文档更改的时间,参见。库尔特的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-01
  • 2011-11-10
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
相关资源
最近更新 更多