65.9K
CodeProject 正在变化。 阅读更多。
Home

小型内容检测库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (11投票s)

2007 年 5 月 1 日

CPOL

3分钟阅读

viewsIcon

53608

downloadIcon

528

介绍一个根据文件内容(和扩展名)检测内容的库。

Screenshot - ContentDetectorLib_01.png

引言

在我最近发表的关于Zeta Uploader应用程序的文章(简而言之,一个上传文件并通过电子邮件发送上传文件链接的网站)中,关于需要管理上传的文件以避免侵犯版权的讨论出现了(感谢Phil.Benson)。

本文介绍了一个我昨晚和今天早上编写的库(所以它非常“新鲜”),它是在正确的方向上迈出的第一步。

该库的功能

因为我想避免(至少现在)强制Zeta Uploader的用户注册和登录才能使用该服务,所以我决定尝试一种不同的方法

文件上传后,会检查该文件是否被认为是“禁止的”,即不能使用 Zeta Uploader 上传。 目前,我已将电影(AVI、MOV 等)和音乐(MP3、WAV 等)等文件列为禁止上传的文件。

该库的工作方式

检测算法使用以下机制来测试文件是被禁止还是允许

  • 文件扩展名

    查看文件扩展名。 如果它与禁止列表中的给定扩展名匹配,则该文件被认为是“禁止的”。

  • 文件内容

    查看文件的前几个字节中已知的二进制模式(“魔术字节”),以匹配禁止模式列表。

  • 存档提取

    如果检测到该文件是存档文件,则会临时提取该文件,并且还会扫描提取的文件(如果它们也包含存档,则会递归地扫描)。

下一节简要讨论这些不同的机制。

文件扩展名检查

这将直接检查文件名的扩展名。 由于这很容易作弊,因此文件扩展名检查仅作为第一次快速检查。 如果匹配,则会为给定的文件完成整个检测。

如果不是,则会进行内容分析,如下所述。

内容分析

该库的主要工作是对文件内容应用简单的“模式匹配”。 通过可扩展的ISignatureChecker接口,以后可以添加更复杂的测试。 我已经包含了一个简单的 MP3 检查,它不仅仅是模式匹配(类Mp3SignatureChecker)。

ISignatureCheckerinterface定义如下

/// <summary>
/// Interface to implement when checking a buffer
/// for a certain signature.
/// </summary>
internal interface ISignatureChecker
{
    /// <summary>
    /// Check whether a given buffer matches the signature.
    ///
    /// <param name="buffer">The buffer.</param>
    /// <returns></returns>
    bool MatchesSignature(
        byte[] buffer );

    /// <summary>
    /// Gets the first number of bytes to read.
    /// </summary>
    /// <value>The first number of bytes to read.</value>
    int FirstNumberOfBytesToRead
    {
        get;
    }

    /// <summary>
    /// Gets the minimum length of the required buffer.
    /// </summary>
    /// <value>The minimum length of the required buffer.</value>
    int MinimumRequiredBufferLength
    {
        get;
    }
}

通过此interface,检查引擎与离散接口进行通信。 有关详细信息和示例,请参见源文件。

存档提取

由于大多数文件都是压缩存档,因此提取这些文件也很重要。

同样,我已经构建了一个基于IArchiveExtractorinterface的可扩展的迷你框架,以便将来添加更多存档提取器。

interface定义如下

/// <summary>
/// Interface for archive extractors.
///
internal interface IArchiveExtractor
{
    /// <summary>
    /// Extracts the specified file path.
    /// </summary>
    /// <param name="filePath">The file path.</param>
    /// <param name="folderPathToExtractInto">The folder path
    /// to extract into.</param>
    void Extract(
        FileInfo filePath,
        DirectoryInfo folderPathToExtractInto );
}

目前,我使用SharpZipLib来为ZIPgzipbzip2提供提取器。

测试应用程序

下载中没有测试应用程序。 相反,以下代码段是我自己的测试控制台应用程序的完整Main函数。

/// <summary>
/// The main function.
/// </summary>
private static void Main()
{
    // Instantiate the engine.
    ContentDetectorEngine engine = new ContentDetectorEngine();

    // --
    // Testing discrete files.

    // Collect some files to test.
    FileInfo[] filePaths = new FileInfo[]
    {
        new FileInfo( @"c:\AnotherFolder\112431940.mp3" ),
        new FileInfo( @"c:\AnotherFolder\247293565.txt" ),
        new FileInfo( @"c:\AnotherFolder\008284502.zip" ),
        new FileInfo( @"c:\AnotherFolder\190243241.mdb" ),
        new FileInfo( @"c:\AnotherFolder\182944456.zip" ),
    };

    // Iterate over the files.
    foreach ( FileInfo filePath in filePaths )
    {
        bool contains =
            engine.ContainsFileProhibitedContent( filePath );
        Console.WriteLine(
            @"Contains '{0}': {1}.",
            filePath.Name,
            contains );
    }

    // --
    // Testing a complete folder.

    // Find all files in the given folder.
    FileInfo[] prohibitedPaths =
        engine.ContainsFolderProhibitedContent(
        new DirectoryInfo(
        @"C:\SomeFolder" ) );

    Console.WriteLine( @"Folder contains {0} prohibited files.",
        prohibitedPaths.Length );

    foreach ( FileInfo prohibitedPath in prohibitedPaths )
    {
        Console.WriteLine(
            @"\tProhibited file: '{0}'.", prohibitedPath );
    }
}

只需将其复制到您自己的控制台应用程序中即可。

结论

在本文中,我向您展示了一个基于文件内容检测文件类型的库。 虽然这只是该库的第一个版本,并且可能某些方法有些幼稚,但我确信该代码很有用,并且将来可以扩展为更可用。

如果您有反馈,问题或评论,只需在下面的评论部分中发布即可。 我期待您的消息!

参考文献

  1. HeaderSig.txt - 几种文件类型的签名
  2. 魔术数字(编程) - 维基百科文章

历史

  • 2007-05-01: 初始版本的库
© . All rights reserved.