【问题标题】:How to make a checksum for a whole USB drive?如何为整个 USB 驱动器制作校验和?
【发布时间】:2019-02-11 23:54:02
【问题描述】:

我需要为整个 USB 驱动器创建校验和。我希望能够在我将文件放入 USB 驱动器时获得整个 USB 驱动器的校验和,然后稍后能够获得另一个校验和以检查是否没有任何变化(病毒、文件更新等)。

现在,我正在查找所有单个文件的校验和,将它们放入 StringBuilder,然后在放置所有校验和后获取该 StringBuilder 的校验和。

private string ChecksumFolder(string path)
{
    string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);

    StringBuilder allChecksum = new StringBuilder();

    for (int count = 0; count < files.Length; count++)
    {
        allChecksum.Append(CreateChecksumFromFile(files[count]));
    }

    return CreateChecksumFromString(allChecksum.ToString());
}

我遇到了“系统卷信息”文件夹的问题,这导致Directory.GetFiles() 行出现异常。文件的校验和和StringBuilder 在用于其他文件夹时工作得很好。

您是否知道为整个 USB 创建校验和的另一种方法或以编程方式进入该系统卷信息文件夹的方法?

提前致谢!

编辑:添加 CreateChecksumFromFile(String 版本基本相同,只是使用不同类型的流进行校验和)

private string CreateChecksumFromFile(string file)
{
    string mChecksum;
    using (FileStream stream = File.OpenRead(file))
    {
        SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
        byte[] checksum = sha.ComputeHash(stream);
        mChecksum = BitConverter.ToString(checksum).Replace("-", String.Empty);
        sha.Clear();
    }
    return mChecksum;
}

【问题讨论】:

  • 有什么例外? CreateChecksumFromString()CreateChecksumFromFile() 方法是什么样的?另外,一个相关提示,使用EnumerateFiles() 而不是GetFiles(),因为它更快。
  • 这是一个 UnauthorizedAccessException,带有消息“访问路径 'E:\System Volume Information' 被拒绝。”此外,该程序请求管理权限
  • 你可以用谷歌搜索那个特殊的“系统卷信息”文件夹是什么。我不知道哈希/校验和值的用途是什么,但我倾向于建议从校验和计算中排除此类特定于系统的文件夹。
  • 好的,这很容易解释 - 您正在尝试访问您无权访问的文件。
  • 我猜这行会抛出异常? using (FileStream stream = File.OpenRead(file)) 我会避免那些无法访问的文件并计算其余文件的校验和。

标签: c# usb checksum


【解决方案1】:

好的,所以你有一个两部分的问题。

  1. 您想要遍历目录中的所有文件并创建校验和。
  2. 可能有一些无法访问的文件,但您也需要一种将它们包含到校验和中的方法。

所以我提出了一种解决方法。 - 如果文件可访问,请为其创建校验和。 - 如果没有,请将文件名添加到列表中。 - 稍后,在验证完整性时,我们会同时验证校验和和不可访问文件列表。

因此,假设以下方法使用example in this SO answer 并创建可访问文件的列表。而且,此外,如果文件不可访问,它会将其添加到列表中。

private static void FindFiles(string path, string file_pattern, bool recurse, out List<string> accessible, out List<string> inaccessible)
{
    accessible = new List<string>();
    inaccessible = new List<string>();
    // This creates two lists, one with accessible files and one with inaccessible files.
}

现在让我们修改你的方法。

private string ChecksumFolder(string path, out List<string> inaccessibleFiles)
{
    inaccessibleFiles = null;

    FindFiles(path, "*", true, out List<string> accessible, out List<string> inaccessible);
    inaccessibleFiles = inaccessible;

    StringBuilder allChecksum = new StringBuilder();

    for (int count = 0; count < accessible.Count; count++)
    {
        allChecksum.Append(CreateChecksumFromFile(accessible[count]));
    }

    return CreateChecksumFromString(allChecksum.ToString());
}

现在您通过使用所有可访问文件和不可访问文件列表获得了该文件夹的校验和。您保存两者,并将它们发送到稍后将验证完整性的任何应用程序。最后你匹配校验和,并查看不可访问文件列表中的文件是否相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    相关资源
    最近更新 更多