【问题标题】:zlib.error Error -3 while decompressing: incorrect header checkzlib.error 解压时出错 -3:不正确的标头检查
【发布时间】:2019-12-30 09:44:36
【问题描述】:

我有一组 .pdf 文件,使用 pdf-parser.py 时会给出:FlateDecode 解压缩失败。 zlib.error 解压时出错 -3:不正确的标头检查。见下文。

    PDF Comment %PDF-1.4 
    PDF Comment %âãÏÓ
    obj 1 0
     Type: /ExtGState
     Referencing: 
    <<
    /Type/ExtGState
    /SA false
    /SM 0.02
    >>
      <<
        /Type /ExtGState
        /SA false
        /SM 0.02
      >>
    <<
    /Type/ExtGState
    /SA false
    /SM 0.02
    >>
    obj 2 0
     Type: 
     Referencing: 
    [/DeviceRGB]
    [/DeviceRGB]
    obj 3 0
     Type: 
     Referencing: 
     Contains stream
      <<
        /Filter /FlateDecode
        /Length 1136
      >>
     FlateDecode decompress failed. zlib.error Error -3 while decompressing: incorrect header check
...
...
<<
/Producer (tx_pdf 15.0.130.501)
/CreationDate (D:20100309081052Z)
>>

ZLIB 标头(在 RFC1950 中定义)应该是:

 CMF |  FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression 

在 010 编辑器中检查文件时,标题字节改为 0x78 和 0xC3。见图片:

有谁知道这些字节可能代表哪种压缩?我试图用谷歌搜索生产者 (/Producer (tx_pdf 15.0.130.501)) 没有结果。

【问题讨论】:

  • Cam 你分享其中一个 pdf 文件进行分析?
  • 文件可能包含受限内容。直接发给你可以吗?
  • 你可以但显然只有我可以分析,而不是这里的所有其他读者。我确实对 pdf 有所了解,但对 pdf-parser.py 不了解。此外,我这周不在办公室,下周之前只有有限的分析工具。尽管如此,如果您发送它,我会尝试提供帮助。您在我的堆栈溢出配置文件中找到了一个电子邮件地址。
  • 一个示例文件已被转发...
  • 我首先看了你的示例 pdf。显然,某些软件将其处理为某种 ANSI 编码的文本,并使用 UTF-8 写回该“文本”。这当然会扰乱每个二进制部分,例如Flate 编码的压缩流。我还没有机会检查这是否以可逆的方式发生(允许维修)。

标签: pdf zlib


【解决方案1】:

显然,某些软件将您的 PDF 处理为某种 ANSI 编码的纯文本,并使用 UTF-8 写回该“文本”。这当然会扰乱每个二进制部分,例如Flate 编码的压缩流。

在您的情况下,ZLIB 标头已经损坏:

78 C3 9A ...

如果您使用 UTF-8 解码得到字符

xÚ...

如果你用一些匹配的 Windows ANSI 编码对这些字符进行编码,你会得到

78 DA ...

这是一个最佳压缩 ZLIB 标头。

因此,您应该尝试撤消此“文本编码更改”。当然,问题仍然是究竟要使用哪种编码,因为该类型有许多非常相似的编码,有些只是在一个字符上有所不同。

另一个问题是,所讨论的软件是否不仅仅是“更改文本编码”——将字节流视为文本的软件有时也会进行其他更改,例如将“行尾”统一到本地平台标准或解释或删除控制字符。此类额外更改很可能会损坏二进制文件,无法修复。

后来对提供的文件进行了一些试验和错误,结果发现这里的 ANSI'ish 编码是 Microsoft 的 .Net Encoding 类称为 windows-1252 的编码,幸运的是有问题的程序似乎没有损坏数据。

因此,使用这几行

byte[] bytes = File.ReadAllBytes(@"rec1254.pdf");
byte[] converted = Encoding.Convert(UTF8Encoding.UTF8, Encoding.GetEncoding("windows-1252"), bytes);
File.WriteAllBytes(@"rec1254-utf8-to-windows-1252.pdf", converted);

我可以修复您的示例文件。在 Python 中进行这种重新编码应该同样简单。

【讨论】:

  • 首先 - 感谢您的努力。高度赞赏。我试图将您的代码转换为 python:#!/usr/bin/python import codecs import sys inFile = sys.argv[1] outFile = sys.argv[2] with codecs.open(inFile, 'r', encoding='utf8') as in_file:lines = in_file.read() # print(lines) #write output file with codecs.open(outFile, 'w', encoding='cp1252') as out_file: out_file.write(lines ) 以上 sn-p 只抱怨“UnicodeEncodeError: 'charmap' codec can't encode character '\x90' in position ...” 我必须进一步调查。
【解决方案2】:

您的 PDF 很可能已加密。如果 Adob​​e Reader 打开它,可能密码为空,但内容仍然是加密的。

PDF 1.7 spec #7.6 Encryption

可以对文档进行加密以保护其内容免受未经授权的侵害 使用权。加密适用于文档中的所有字符串和流 PDF 文件有以下例外:

  • 预告片中 ID 条目的值

  • 加密字典中的任何字符串

  • 流中的任何字符串,例如内容流和压缩对象流,它们本身是加密的

这意味着您需要在放气之前解密您的流。

【讨论】:

  • 我检查了通过邮件提供的 OP 的 PDF。它没有加密。它被某些程序像纯文本文件一样处理。
  • 我将@mkl 建议的解决方案转换为一个.net sn-p 解决方案。在 UTF-8 到 windows-1252 的转换之后,所有文件都是可读的。谢谢。
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 2022-11-13
相关资源
最近更新 更多