在 UWP 中使用 IBuffer 计算文件的哈希值
Using IBuffer to compute hash of the file in UWP
我不知道如何在 UWP 中计算大文件的哈希值。哈希算法接受 IBuffer 接口作为数据参数,它无法从流中获取数据。只有两种方式看起来都是死胡同:
- 无法将整个文件加载到内存中,因为文件可能太大。
- 使用 IBuffer 接口实现某种流 reader 似乎也不可行,因为 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 哈希值?
Hashing algorithm accepts IBuffer interface as data parameter which has no way to get data from the stream.
我们可以通过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);
Implementing some kind of stream reader with IBuffer interface does not seem viable either as IBuffer only has two properties: Length and Capacity
IInputStream.ReadAsync
方法可以读取流到缓冲区。提供buffer参数读取InputStream
到buffer。如果要读取大文件,可以定义buffer的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。
我不知道如何在 UWP 中计算大文件的哈希值。哈希算法接受 IBuffer 接口作为数据参数,它无法从流中获取数据。只有两种方式看起来都是死胡同:
- 无法将整个文件加载到内存中,因为文件可能太大。
- 使用 IBuffer 接口实现某种流 reader 似乎也不可行,因为 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 哈希值?
Hashing algorithm accepts IBuffer interface as data parameter which has no way to get data from the stream.
我们可以通过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);
Implementing some kind of stream reader with IBuffer interface does not seem viable either as IBuffer only has two properties: Length and Capacity
IInputStream.ReadAsync
方法可以读取流到缓冲区。提供buffer参数读取InputStream
到buffer。如果要读取大文件,可以定义buffer的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。