2012-11-02 41 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:謝謝你的提示。 (爲了保持簡單,我最初忽略了這個事實,但是我忽略了認爲這可能導致人們構建過於簡單的解決方案,然後就無法工作)。我會相應地更新我的答案。 –