How do I use the SHA1CryptoServiceProvider()
on a file to create a SHA1 Checksum of the file?
Asked
Active
Viewed 5.3k times
4 Answers
86
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
contains the string representation of the SHA-1 hash. Also, by using a FileStream
instead of a byte buffer, ComputeHash
computes the hash in chunks, so you don't have to load the entire file in one go, which is helpful for large files.

Eric J.
- 147,927
- 63
- 340
- 553
-
3You should use a `StringBuilder` instead of generating 20 strings in the process of building the hash string. – Igor Brejc Mar 29 '11 at 18:25
-
`FileStream` is `IDisposable` and should also be used in a `using` block. – Bradley Grainger May 14 '11 at 06:28
-
3StringBuilder initial capacity should be twice the number of bytes in the hash – Mark Heath Jun 12 '12 at 11:43
-
1Edited to reflect @MarkHeath's comment and added a BufferedStream to improve performance. – Eric J. Oct 06 '12 at 01:34
-
11I don't think you need to use BufferedStream. http://stackoverflow.com/a/2069317/64334 – Ronnie Overby Oct 17 '12 at 21:23
-
1Tested with 100,000 iterations, BufferedStream makes no difference, so I'm going to remove it from the example. I also tested an alternate way of generating the string of the hash, using BitConverter, and it offers a moderate (6%) performance increase (and less LoC), so modifying that in the example as well. – Mason G. Zhwiti Mar 28 '13 at 18:02
-
Easier way to convert bytes to string: `Convert.ToBase64String(hash)` – Roland Nov 10 '15 at 10:36
-
@Roland - That is not an equivalent representation. The example is hex, not base 64. However, you could do `BitConverter.ToString(hash).Replace("-","")` – Broots Waymb Jan 05 '17 at 21:37
-
This solution will be quite slow, especially on large files, because `ComputeHash` internally using very small 4k buffer. `FileStream` by default also have 4k buffer. So you need to increase `FileStream` buffer at least. Or, for best performance, completely replace `ComputeHash` with `TransformBlock`/`TransformFinalBlock` pair. – arbiter Jun 26 '17 at 11:19
66
With the ComputeHash method. See here:
Example snippet:
using(var cryptoProvider = new SHA1CryptoServiceProvider())
{
string hash = BitConverter
.ToString(cryptoProvider.ComputeHash(buffer));
//do something with hash
}
Where buffer is the contents of your file.

dreadwail
- 15,098
- 21
- 65
- 96
-
4+1 for a great tip on using the `BitConverter` to generate a hex-string in one go. – Igor Brejc Mar 29 '11 at 18:26
-
1
-
2`BitConverter` separates bytes with a dash AA-F0-CC unlike @mgbowen's solution. May or may not be what is desired. – Eric J. Oct 06 '12 at 01:37
6
If you are already reading the file as a stream, then the following technique calculates the hash as you read it. The only caveat is that you need to consume the whole stream.
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));
}
}

Daniel James Bryars
- 4,429
- 3
- 39
- 57
-
+1 for `CryptoStream`. it could be useful in case you want to read a file from somewhere (eg : from an http request), write it to some place (eg: on disk) and at the same time compute the hash. – tigrou Apr 13 '15 at 14:45
-
1On a test on a large file, this code performed orders of magnitude worse than the `ComputeHash` solutions. Maybe it's the `ReadByte` one-at-a-time reading? – Michael Kropat Dec 22 '15 at 17:09
-
@MichaelKropat interesting. Good to know. 10 times, 100 times slower? – Daniel James Bryars Dec 28 '15 at 16:42
-
@MichaelKropat - just thought, if the overhead is because my example reads every byte, then this is moot if you are using the stream anyway. – Daniel James Bryars Jan 28 '16 at 15:13
3
Also you can try:
FileStream fop = File.OpenRead(@"C:\test.bin");
string chksum = BitConverter.ToString(System.Security.Cryptography.SHA1.Create().ComputeHash(fop));

SNMetamorph
- 51
- 5