【问题标题】:Is it possible to verify that a posted file is pdf or not? [duplicate]是否可以验证发布的文件是否为 pdf? [复制]
【发布时间】:2013-04-07 12:07:15
【问题描述】:

conserned 网站的主要工作是接受用户的文件并保存。直到 2 个月前,当我被告知强制执行仅接受 pdf 文件的约束时,一切都很好。

在此之前,用户有提交各种格式的习惯,从文本、rtf 到好的 pdf。

我通过检查文件扩展名应用了约束 --simple 对吗?然而,当管理员检查这些文件时,大约 60% 的文件已损坏。

我花了很多不眠之夜来确定损坏的原因,然后突然我想可能是他们提交了损坏的文件。

我根据之前的记录,确定了一些我们从中获取损坏文件的用户最喜欢的文件类型格式。

我把扩展改回了最喜欢的扩展和繁荣..文件打开了。

尽管我以粗体字告诉用户如何将文件转换为 pdf,但我了解到的一些(许多)只是更改扩展名并提交。 由于该网站不奖励用户。提交的文件管理人员对我抱怨。有什么方法可以在不依赖扩展名的情况下检查文件是否为 pdf??

我在 c# 3.5 asp.net 中使用文件上传

【问题讨论】:

  • 查看 POST mimetype。
  • 怎么样??我已将其设置为应用程序/二进制
  • 每个 PDF 的开头都有一个特殊的字符序列,请检查一下。
  • 检查文件是否按照PDF规范要求以%PDF-开头:PDF文件的第一行应该是由5个字符%组成的标题PDF– 后跟 1.N 形式的版本号,其中 N 是 0 到 7 之间的数字。(参见ISO-32000-1:2008 第 7.5.2 节。)
  • @mkl 你能给我一些代码吗..这样做

标签: c# asp.net pdf


【解决方案1】:

由于所有 PDF 文件都以 ASCII 字符串“%PDF-”开头,因此只需测试文件的前几个字节以确保它们以该字符串开头。

bool IsPdf(string path)
{
    var pdfString = "%PDF-";
    var pdfBytes = Encoding.ASCII.GetBytes(pdfString);
    var len = pdfBytes.Length;
    var buf = new byte[len];
    var remaining = len;
    var pos = 0;
    using(var f = File.OpenRead(path))
    {
        while(remaining > 0)
        {
            var amtRead = f.Read(buf, pos, remaining);
            if(amtRead == 0) return false;
            remaining -= amtRead;
            pos += amtRead;
        }
    }
    return pdfBytes.SequenceEqual(buf);
}

【讨论】:

  • Thankx 伙计,这很容易,只需对您的代码稍作修改即可工作。再次感谢。
  • 两个cmets。首先,虽然当前的 PDF 规范对此相当严格,但旧的规范并没有那么严格。 Adobe Acrobat 过去(不确定当前版本)接受在文件的前 1024 个字节中包含 %PDF- 字符串的任何文件(并接受它之前的内容为垃圾)。其次,在这种假设下,以文本“%PDF-”开头的简单文本文件将被接受为有效的 PDF 文件。我希望你的文件提交者不是很聪明:)
  • 这是一个复杂的解决方案,用于读取和比较 5 个字节这样简单的事情。
  • 我刚刚拒绝了对这个问题的编辑,它忽略了 read 的返回值,试图“简化”这段代码。 Stream.Read 的返回值永远不应被忽略
  • @MustafaOzturk 如果您觉得有更有效的方法来实现这一目标,请随时提供答案。我很乐意投票。
【解决方案2】:

我发现this site 在帮助确定文件是否与其扩展名匹配方面非常有用。这是一个巨大的文件签名列表,您可以将其与 spender 的代码一起使用。

猜你喜欢
  • 1970-01-01
  • 2013-11-30
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 2018-12-01
相关资源
最近更新 更多