3

我有一个 c# web 应用程序,我想检查 pdf 文档是否包含交叉引用流。如果它包含交叉引用流,则将其转换为引用表。

4

3 回答 3

1

检测相当容易。从文件末尾搜索“%%EOF”;正确的 PDF 文件实际上以 '%%EOF' 行结尾,不太正确的文件可能在该标记后面有一些垃圾字节。该标记线之前的行包含最后一个交叉引用的位置(参见ISO-32000-1:2008第 7.5.5 节的 Adob​​e 副本)。转到此处注明的位置。

如果在该位置找到 xref 关键字,则 PDF 有一个交叉引用表。如果您改为找到 PDF 流对象(同上第 7.5.8 节),则 PDF 具有交叉引用流。如果您在那里都没有找到,那么该文件的某些内容是可疑的。

但是,转换很困难,特别是如果 PDF 还使用只能与交叉引用流一起使用的对象流。您可能希望使用 iText(Sharp) 之类的库来阅读 PDF 并在启用较少压缩的情况下再次导出。

此外,如果 PDF 已签名,则无法在不破坏签名的情况下进行转换。

于 2012-10-16T10:37:58.053 回答
0

从交叉引用流转换为可以解析的内容时要注意的一件事是交叉引用流允许新类型的引用条目。沿着"uncompressed""free"您现在已经将"compressed"作为新的引用类型。

此条目不能直接 1:1 转换为正常的交叉引用表。交叉引用流内的“压缩”引用条目指向所谓的“对象流”。后者包含多个索引对象。外部参照流中的“压缩”条目然后命名对象流和索引。然后使用对象流中的第一行将索引解析为对象流中的字节偏移量。

如果您仍然对该主题感兴趣,我建议您查看“3.4.7 Cross-Reference Streams”一章。尤其是“与不支持 PDF 1.5 的应用程序的兼容性”段落可以提供帮助。它处理所谓的“混合引用”,以某种方式执行您想要的操作。

现在,我们或多或少知道如何将外部参照流转换为外部参照表,让我们继续检测外部参照流。

  • 您可以使用/Type/XRef搜索流(两个关键字之间有可变空格)。
  • 此外,如果您有任何/Type/ObjStm流,您可以推断必须存在外部参照流,因为只有外部参照流可以指向对象流;)(请参阅上文以获取解释)。
  • 最后但并非最不重要的一点是,如果您解析的文档的PDF 版本小于 1.5,您可以确定没有包含外部参照流。这在很大程度上取决于创建文档的 PDF 创作工具。有些人坚持参考有些人不坚持。

我希望这有帮助。

于 2013-08-19T08:48:51.187 回答
0

这是一种 hack,但您可以使用以下代码来检测 PDF 是否包含交叉引用流。

该代码使用Docotic.Pdf 库

public static bool ContainsCrossReferenceStreams(string fileName)
{
    using (PdfDocument document = new PdfDocument(fileName))
    {
        return document.SaveOptions.UseObjectStreams;
    }
}

当库打开 PDF 时,它设置SaveOptions.UseObjectStreamstrue源文档是否使用交叉引用流。否则属性返回false

免责声明:我为图书馆的供应商工作。

于 2012-10-19T19:13:35.383 回答