Skip to main content
added 1123 characters in body
Source Link
Jon Skeet
  • 1.5m
  • 893
  • 9.3k
  • 9.3k

(EDIT: Disposing of the hash algorithms now. I suspect it's unnecessary, but it's good practice :)

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        using (MD5 md5 = MD5.Create();)
        {
            byte[] md5Hash = md5.ComputeHash(plaintext);
            Console.WriteLine(BitConverter.ToString(md5Hash));
        }
        
        using (SHA1 sha1 = SHA1.Create();)
        {
            byte[] sha1Hash = sha1.ComputeHash(plaintext);
            Console.WriteLine(BitConverter.ToString(sha1Hash));
        }
    }
}

Note that this is just the simple way of computing a hash in one go. If you want to do it in a streaming fashion (i.e. where you read some data, add it to the hash, read some more data etc) then either you can use the ComputeHash(Stream) overload or create a(if you want to "push" data to it) you can use CryptoStreamTransformBlock using the hash algorithm asand TransformFinalBlock, like this:

using System.Text;

class Test
{
    static void Main()
    {
        using (MD5 md5 = MD5.Create())
        using (SHA1 sha1 = SHA1.Create())
        using (Stream input = File.OpenRead("b.txt"))
        {
            // Artificially small to make sure there's
            // more than one read
            byte[] buffer = new byte[4];
            int bytesRead;
                        
            while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                md5.TransformBlock(buffer, 0, bytesRead, null, 0);
                sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
            }
            md5.TransformFinalBlock(buffer, 0, 0);
            sha1.TransformFinalBlock(buffer, 0, 0);
            
            Console.WriteLine(BitConverter.ToString(md5.Hash));
            Console.WriteLine(BitConverter.ToString(sha1.Hash));
        }
    }
}

Note the way we pass ICryptoTransformnull to TransformBlock because we don't need any output, and we don't transform any data in the final block. I suspect this is the example you'll want to use, based on your previous comments.

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        MD5 md5 = MD5.Create();
        byte[] md5Hash = md5.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(md5Hash));
        
        SHA1 sha1 = SHA1.Create();
        byte[] sha1Hash = sha1.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(sha1Hash));
    }
}

Note that this is just the simple way of computing a hash in one go. If you want to do it in a streaming fashion (i.e. where you read some data, add it to the hash, read some more data etc) then either you can use the ComputeHash(Stream) overload or create a CryptoStream using the hash algorithm as the ICryptoTransform.

(EDIT: Disposing of the hash algorithms now. I suspect it's unnecessary, but it's good practice :)

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        using (MD5 md5 = MD5.Create())
        {
            byte[] md5Hash = md5.ComputeHash(plaintext);
            Console.WriteLine(BitConverter.ToString(md5Hash));
        }
        
        using (SHA1 sha1 = SHA1.Create())
        {
            byte[] sha1Hash = sha1.ComputeHash(plaintext);
            Console.WriteLine(BitConverter.ToString(sha1Hash));
        }
    }
}

Note that this is just the simple way of computing a hash in one go. If you want to do it in a streaming fashion (i.e. where you read some data, add it to the hash, read some more data etc) then either you can use the ComputeHash(Stream) overload or (if you want to "push" data to it) you can use TransformBlock and TransformFinalBlock, like this:

using System.Text;

class Test
{
    static void Main()
    {
        using (MD5 md5 = MD5.Create())
        using (SHA1 sha1 = SHA1.Create())
        using (Stream input = File.OpenRead("b.txt"))
        {
            // Artificially small to make sure there's
            // more than one read
            byte[] buffer = new byte[4];
            int bytesRead;
                        
            while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                md5.TransformBlock(buffer, 0, bytesRead, null, 0);
                sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
            }
            md5.TransformFinalBlock(buffer, 0, 0);
            sha1.TransformFinalBlock(buffer, 0, 0);
            
            Console.WriteLine(BitConverter.ToString(md5.Hash));
            Console.WriteLine(BitConverter.ToString(sha1.Hash));
        }
    }
}

Note the way we pass null to TransformBlock because we don't need any output, and we don't transform any data in the final block. I suspect this is the example you'll want to use, based on your previous comments.

added 452 characters in body
Source Link
Jon Skeet
  • 1.5m
  • 893
  • 9.3k
  • 9.3k

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

Here's some really simple code to compute the hashes:

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        MD5 md5 = MD5.Create();
        byte[] md5Hash = md5.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(md5Hash));
        
        SHA1 sha1 = SHA1.Create();
        byte[] sha1Hash = sha1.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(sha1Hash));
    }
}

This gives the results as per wikipedia - note that b.txt shouldn't have a newline at the end of it.

An alternative way of getting the binary data to start with would be:

byte[] plaintext = Encoding.ASCII.GetBytes(
    "The quick brown fox jumps over the lazy dog");

Note that this is just the simple way of computing a hash in one go. If you want to do it in a streaming fashion (i.e. where you read some data, add it to the hash, read some more data etc) then either you can use the ComputeHash(Stream) overload or create a CryptoStream using the hash algorithm as the ICryptoTransform.

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

Here's some really simple code to compute the hashes:

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        MD5 md5 = MD5.Create();
        byte[] md5Hash = md5.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(md5Hash));
        
        SHA1 sha1 = SHA1.Create();
        byte[] sha1Hash = sha1.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(sha1Hash));
    }
}

This gives the results as per wikipedia - note that b.txt shouldn't have a newline at the end of it.

An alternative way of getting the binary data to start with would be:

byte[] plaintext = Encoding.ASCII.GetBytes(
    "The quick brown fox jumps over the lazy dog");

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

Here's some really simple code to compute the hashes:

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        MD5 md5 = MD5.Create();
        byte[] md5Hash = md5.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(md5Hash));
        
        SHA1 sha1 = SHA1.Create();
        byte[] sha1Hash = sha1.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(sha1Hash));
    }
}

This gives the results as per wikipedia - note that b.txt shouldn't have a newline at the end of it.

An alternative way of getting the binary data to start with would be:

byte[] plaintext = Encoding.ASCII.GetBytes(
    "The quick brown fox jumps over the lazy dog");

Note that this is just the simple way of computing a hash in one go. If you want to do it in a streaming fashion (i.e. where you read some data, add it to the hash, read some more data etc) then either you can use the ComputeHash(Stream) overload or create a CryptoStream using the hash algorithm as the ICryptoTransform.

Source Link
Jon Skeet
  • 1.5m
  • 893
  • 9.3k
  • 9.3k

You're calling ComputeHash for the whole buffer even though you should only be hashing the portion of the buffer you've read. In addition, you're computing a new hash for each call to Read.

Here's some really simple code to compute the hashes:

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        MD5 md5 = MD5.Create();
        byte[] md5Hash = md5.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(md5Hash));
        
        SHA1 sha1 = SHA1.Create();
        byte[] sha1Hash = sha1.ComputeHash(plaintext);
        Console.WriteLine(BitConverter.ToString(sha1Hash));
    }
}

This gives the results as per wikipedia - note that b.txt shouldn't have a newline at the end of it.

An alternative way of getting the binary data to start with would be:

byte[] plaintext = Encoding.ASCII.GetBytes(
    "The quick brown fox jumps over the lazy dog");