【问题标题】:Using IBuffer to compute hash of the file in UWP在 UWP 中使用 IBuffer 计算文件的哈希值
【发布时间】:2017-05-07 16:09:04
【问题描述】:

我不知道如何在 UWP 中计算大文件的哈希值。哈希算法接受 IBuffer 接口作为数据参数,无法从流中获取数据。只有两种方式看起来都是死胡同:

  1. 无法将整个文件加载到内存中,因为文件可能太大。
  2. 使用 IBuffer 接口实现某种流读取器似乎也不可行,因为 IBuffer 只有两个属性:长度和容量。

这是来自 MSDN 的精简示例,它显示了当数据在字符串中时如何使用算法。

IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(strMsg, BinaryStringEncoding.Utf8);
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg);
string hex = CryptographicBuffer.EncodeToHexString(buffHash);

在不编写自己的算法或使用第三方组件的情况下,如何在 UWP 中计算大文件的 MD5 哈希?

【问题讨论】:

    标签: c# hash cryptography uwp md5


    【解决方案1】:

    哈希算法接受 IBuffer 接口作为数据参数,无法从流中获取数据。

    我们可以通过FileIO.ReadBufferAsync 方法直接从文件中读取缓冲区。然后你可以散列它。代码如下:

       StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/P408.mp4"));
       IBuffer filebuffer = await FileIO.ReadBufferAsync(file);
       //IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(strMsg, BinaryStringEncoding.Utf8);
       HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
       IBuffer buffHash = objAlgProv.HashData(filebuffer);
       string hex = CryptographicBuffer.EncodeToHexString(buffHash);
    

    使用 IBuffer 接口实现某种流读取器似乎也不可行,因为 IBuffer 只有两个属性:长度和容量

    IInputStream.ReadAsync 方法可以将流读取到缓冲区。它提供缓冲区参数来读取InputStream 到缓冲区。如果要读取大文件,可以将缓冲区的capacity 定义为读取文件的部分。代码如下:

    HashAlgorithmProvider alg = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
    StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/P408.mp4"));
    var stream = await file.OpenStreamForReadAsync();
    var inputStream = stream.AsInputStream();
    uint capacity = 100000000;
    Windows.Storage.Streams.Buffer buffer = new Windows.Storage.Streams.Buffer(capacity);
    var hash = alg.CreateHash();
    while (true)
    {
        await inputStream.ReadAsync(buffer, capacity, InputStreamOptions.None);
        if (buffer.Length > 0)
            hash.Append(buffer);
        else
            break;
    }
    string hashText = CryptographicBuffer.EncodeToHexString(hash.GetValueAndReset()).ToUpper();
    inputStream.Dispose();
    stream.Dispose();
    

    更多详情请参考official sample

    【讨论】:

      猜你喜欢
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      • 2023-03-14
      • 2014-04-01
      • 2016-06-23
      • 2015-12-18
      • 2013-06-07
      相关资源
      最近更新 更多