title: SHA-1 Hash a byte array vs a file stream
body: <p>I am writing an API that allows users to upload files (image, video, etc). I use a SHA-1 hash to make sure the same file isn't uploaded multiple times. Previously we only allowed smaller files so I was reading them into a byte array and hashing that but now we allow larger files so I am using a file stream. The problem is the SHA-1 algorithm returns a different hash. I need to figure out how to get the same hash regardless of the method, even if I have to turn the byte array into a file stream or something. However, I've tried writing the byte array to a temp file and reading it in and it returns the same hash as the byte array. Here is an example console app that shows what I am doing:</p>
  
  <pre><code>static void Main(string[] args)
  {
      string file = "C:\\CUWCDFileStorage\\temp\\test.png";
      var bytes = File.ReadAllBytes(file);
      using (var stream = File.Open(file, FileMode.Open))
      {
          Console.WriteLine(Sha1HashFile(bytes));   // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80
          Console.WriteLine(Sha1HashFile(stream));  // Returns DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
          Console.WriteLine(Sha1HashFile2(bytes));  // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80
      }
  
      Console.Read();
  }
  
  public static string Sha1HashFile(byte[] file)
  {
      using (SHA1Managed sha1 = new SHA1Managed())
      {
          return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", "");
      }
  }
  
  public static string Sha1HashFile(Stream stream)
  {
      using (SHA1Managed sha1 = new SHA1Managed())
      {
          return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", "");
      }
  }
  
  public static string Sha1HashFile2(byte[] bytes)
  {
      string file = "C:\\CUWCDFileStorage\\temp\\test2.png";
      File.WriteAllBytes(file, bytes);
      return Sha1HashFile(File.OpenRead(file));
  }
  </code></pre>
  
  <p>I've even tried to just put the byte array into a <code>MemoryStream</code> with <code>new MemoryStream(bytes)</code> but that didn't work either. It seems like once I have the file in a byte array it can't be put back.</p>
  
  <p>EDIT:</p>
  
  <p>I removed some code from my example because I thought MD5 was working. Here is the original code I was using to test:</p>
  
  <pre><code>static void Main(string[] args)
  {
      string file = "C:\\CUWCDFileStorage\\temp\\test.png";
      var bytes = File.ReadAllBytes(file);
      using (var stream = File.Open(file, FileMode.Open))
      {
          Console.WriteLine(Md5HashFile(bytes));
          Console.WriteLine(Md5HashFile(stream));
          Console.WriteLine(Sha1HashFile(bytes));
          Console.WriteLine(Sha1HashFile(stream));
          Console.WriteLine(Sha1HashFile2(bytes));
      }
  
      Console.Read();
  }
  
  public static string Md5HashFile(byte[] file)
  {
      using (MD5 md5 = MD5.Create())
      {
          return BitConverter.ToString(md5.ComputeHash(file)).Replace("-", "");
      }
  }
  
  public static string Sha1HashFile(byte[] file)
  {
      using (SHA1Managed sha1 = new SHA1Managed())
      {
          return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", "");
      }
  }
  
  public static string Md5HashFile(Stream stream)
  {
      using (MD5 md5 = MD5.Create())
      {
          return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "");
      }
  }
  
  public static string Sha1HashFile(Stream stream)
  {
      using (SHA1Managed sha1 = new SHA1Managed())
      {
          return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", "");
      }
  }
  
  public static string Sha1HashFile2(byte[] bytes)
  {
      string file = "C:\\CUWCDFileStorage\\temp\\test2.png";
      File.WriteAllBytes(file, bytes);
      return Sha1HashFile(File.OpenRead(file));
  }
  </code></pre>
  
  <p>See answer below for explanation of the problem.</p>