【发布时间】:2010-12-31 22:08:33
【问题描述】:
如何使用文件上的SHA1CryptoServiceProvider() 来创建文件的 SHA1 校验和?
【问题讨论】:
如何使用文件上的SHA1CryptoServiceProvider() 来创建文件的 SHA1 校验和?
【问题讨论】:
using (FileStream fs = new FileStream(@"C:\file\location", FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs))
{
using (SHA1Managed sha1 = new SHA1Managed())
{
byte[] hash = sha1.ComputeHash(bs);
StringBuilder formatted = new StringBuilder(2 * hash.Length);
foreach (byte b in hash)
{
formatted.AppendFormat("{0:X2}", b);
}
}
}
formatted 包含 SHA-1 哈希的字符串表示形式。此外,通过使用FileStream 而不是字节缓冲区,ComputeHash 以块的形式计算哈希,因此您不必一次性加载整个文件,这对大文件很有帮助。
【讨论】:
StringBuilder,而不是在构建哈希字符串的过程中生成20个字符串。
使用 ComputeHash 方法。见这里:
示例 sn-p:
using(var cryptoProvider = new SHA1CryptoServiceProvider())
{
string hash = BitConverter
.ToString(cryptoProvider.ComputeHash(buffer));
//do something with hash
}
其中缓冲区是文件的内容。
【讨论】:
BitConverter 一次性生成十六进制字符串的重要提示。
using 块中
BitConverter 用破折号 AA-F0-CC 分隔字节,这与 @mgbowen 的解决方案不同。可能是也可能不是我们想要的。
如果您已经将文件作为流读取,则以下技术会在您读取文件时计算哈希值。唯一需要注意的是,您需要消耗整个流。
class Program
{
static void Main(string[] args)
{
String sourceFileName = "C:\\test.txt";
Byte[] shaHash;
//Use Sha1Managed if you really want sha1
using (var shaForStream = new SHA256Managed())
using (Stream sourceFileStream = File.Open(sourceFileName, FileMode.Open))
using (Stream sourceStream = new CryptoStream(sourceFileStream, shaForStream, CryptoStreamMode.Read))
{
//Do something with the sourceStream
//NOTE You need to read all the bytes, otherwise you'll get an exception ({"Hash must be finalized before the hash value is retrieved."})
while(sourceStream.ReadByte() != -1);
shaHash = shaForStream.Hash;
}
Console.WriteLine(Convert.ToBase64String(shaHash));
}
}
【讨论】:
CryptoStream。如果您想从某个地方读取文件(例如:从 http 请求),将其写入某个地方(例如:磁盘上)并同时计算哈希,它可能会很有用。
ComputeHash 解决方案差几个数量级。也许是ReadByte 一次阅读?
你也可以试试:
FileStream fop = File.OpenRead(@"C:\test.bin");
string chksum = BitConverter.ToString(System.Security.Cryptography.SHA1.Create().ComputeHash(fop));
【讨论】: