2012-11-02 39 views
4

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

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

这些“哈希”是什么?我该如何删除它们?使用PDFTK

 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(); 

和提取的文件METAS:

IM使用下面的代码从iText的包装改变metainfos

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 

感谢任何提示

+0

我在生成SHA1和时具有与这些ID完全相同的问题。你有没有想过如何去除/规范化这个问题,或者你知道下面的信息后就放弃了吗? – mlissner

回答

1

关于标识符...的PDF规范说:

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

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

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

+0

所以它不可能跳过插入标识符(例如通过属性)与可用的iText版本?我需要自己修改它才能做到这一点? – metar

+0

是的。毕竟,没有改变id的文档更改是不受欢迎的行为。 – mkl

+0

如果您打算更改iText,请记住,在pdf中还有许多其他条目,这些条目至少取决于上次文档更改的时间。库尔特的回答。 – mkl

6

什么你请参阅标记为PdfID0PdfID1pdftk的元数据转储是以下PDF的一部分trailer代码在相应的PDF文件(例如)的端部:

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

在拖车字典中的条目/ID如果Encrypt条目存在时,才需要;否则它是一个可选的关键。

它由PDF规格描述为:

“构成文件的标识符的两个字节的字符串数组(见14.4,‘文件标识符’)用于文件如果有一个加密入口这个数组和两个字节字符串应该是直接对象,并且应该是未加密的。“

进而:

“的第一个字节串应根据它最初创建时的文件内容不变的标识符,当文件被增量更新不应改变。第二个字节的字符串应该是根据上次更新时文件内容的变化标识符,当第一次写入文件时,两个标识符应设置为相同的值,如果在解析文件引用时两个标识符匹配,很可能找到了正确和未更改的文件,如果只有第一个标识符匹配,则找到了不同版本的正确文件。“

它是 necesarrily 哈希。这里是什么ISO PDF规范表明(不是“规定”):

“为了帮助确保文件标识符的唯一性,就应该通过消息的方式摘要算法,如MD5计算(描述因特网RFC 1321,的MD5消息摘要算法;见参考文献),使用以下信息:

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

有几个点在生成的PDF文件可能随着每次新的运行而改变。在文档信息字典这些键(/Info条目在拖车中引用)

  • /CreationDate
  • /ModDate

可每次创建或修改PDF时更新。

因此,使用自己的MD5校验和在生产PDF检查新/更改的文件将无法正常工作,除非你要确保你至少是“正常化”的/CreationDate/ModDate还有/ID条目,再创建你的MD5哈希。


更新:作为用户MKL在这个答案评论正确地指出的那样,/Info字典的/CreationDate/ModDate键(还有/ID信息)通常包含的信息的等效件嵌入在PDF中的XML元数据。您可以使用pdfinfo工具的帮助下,像这样显示完整的XML元数据:

pdfinfo -meta your.pdf 
+0

除了这些信息词典条目之外,XML元数据流中可能有相同的条目。 – mkl

+0

@mkl:谢谢你的提示。 (为了保持简单,我最初忽略了这个事实,但是我忽略了认为这可能导致人们构建过于简单的解决方案,然后就无法工作)。我会相应地更新我的答案。 –