C# 计算文件的 Hash 值

/// <summary>

  /// 提供用于计算指定文件哈希值的方法

  /// <example>例如计算文件的MD5值:

  /// <code>

  ///   String hashMd5=HashHelper.ComputeMD5("MyFile.txt");

  /// </code>

  /// </example>

  /// <example>例如计算文件的CRC32值:

  /// <code>

  ///   String hashCrc32 = HashHelper.ComputeCRC32("MyFile.txt");

  /// </code>

  /// </example>

  /// <example>例如计算文件的SHA1值:

  /// <code>

  ///   String hashSha1 =HashHelper.ComputeSHA1("MyFile.txt");

  /// </code>

  /// </example>

  /// </summary>

  public sealed class HashHelper

  {

      /// <summary>

      ///  计算指定文件的MD5值

      /// </summary>

      /// <param name="fileName">指定文件的完全限定名称</param>

      /// <returns>返回值的字符串形式</returns>

      public static String ComputeMD5(String fileName)

      {

          String hashMD5 = String.Empty;

          //检查文件是否存在,如果文件存在则进行计算,否则返回空值

          if (System.IO.File.Exists(fileName))

          {

              using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))

              {

                  //计算文件的MD5值

                  System.Security.Cryptography.MD5 calculator=System.Security.Cryptography.MD5.Create();

                  Byte[] buffer = calculator.ComputeHash(fs);

                  calculator.Clear();

                  //将字节数组转换成十六进制的字符串形式

                  StringBuilder stringBuilder = new StringBuilder();

                  for (int i = 0; i < buffer.Length; i++)

                  {

                      stringBuilder.Append(buffer[i].ToString("x2"));

                  }

                 hashMD5= stringBuilder.ToString();

              }//关闭文件流

          }//结束计算

          return hashMD5;

      }//ComputeMD5

      /// <summary>

      ///  计算指定文件的CRC32值

      /// </summary>

      /// <param name="fileName">指定文件的完全限定名称</param>

      /// <returns>返回值的字符串形式</returns>

      public static String ComputeCRC32(String fileName)

      {

          String hashCRC32 = String.Empty;

          //检查文件是否存在,如果文件存在则进行计算,否则返回空值

          if (System.IO.File.Exists(fileName))

          {

              using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))

              {

              //计算文件的CSC32值

              Crc32 calculator = new Crc32();

              Byte[] buffer = calculator.ComputeHash(fs);

              calculator.Clear();

              //将字节数组转换成十六进制的字符串形式

              StringBuilder stringBuilder = new StringBuilder();

              for (int i = 0; i < buffer.Length; i++)

              {

                  stringBuilder.Append(buffer[i].ToString("x2"));

              }

              hashCRC32 = stringBuilder.ToString();

              }//关闭文件流

          }

          return hashCRC32;

      }//ComputeCRC32

      /// <summary>

      ///  计算指定文件的SHA1值

      /// </summary>

      /// <param name="fileName">指定文件的完全限定名称</param>

      /// <returns>返回值的字符串形式</returns>

      public static String ComputeSHA1(String fileName)

      {

          String hashSHA1 = String.Empty;

          //检查文件是否存在,如果文件存在则进行计算,否则返回空值

          if (System.IO.File.Exists(fileName))

          {

              using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))

              {

                  //计算文件的SHA1值

                  System.Security.Cryptography.SHA1 calculator = System.Security.Cryptography.SHA1.Create();

                  Byte[] buffer = calculator.ComputeHash(fs);

                  calculator.Clear();

                  //将字节数组转换成十六进制的字符串形式

                  StringBuilder stringBuilder = new StringBuilder();

                  for (int i = 0; i < buffer.Length; i++)

                  {

                      stringBuilder.Append(buffer[i].ToString("x2"));

                  }

                  hashSHA1 = stringBuilder.ToString();

              }//关闭文件流

          }

          return hashSHA1;

      }//ComputeSHA1

  }//end class: HashHelper

   /// <summary>

   /// 提供 CRC32 算法的实现

   /// </summary>

   public class Crc32 : System.Security.Cryptography.HashAlgorithm

   {

       public const UInt32 DefaultPolynomial = 0xedb88320;

       public const UInt32 DefaultSeed = 0xffffffff;

       private UInt32 hash;

       private UInt32 seed;

       private UInt32[] table;

       private static UInt32[] defaultTable;

       public Crc32()

       {

           table = InitializeTable(DefaultPolynomial);

           seed = DefaultSeed;

           Initialize();

       }

       public Crc32(UInt32 polynomial, UInt32 seed)

       {

           table = InitializeTable(polynomial);

           this.seed = seed;

           Initialize();

       }

       public override void Initialize()

       {

           hash = seed;

       }

       protected override void HashCore(byte[] buffer, int start, int length)

       {

           hash = CalculateHash(table, hash, buffer, start, length);

       }

       protected override byte[] HashFinal()

       {

           byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);

           this.HashValue = hashBuffer;

           return hashBuffer;

       }

       public static UInt32 Compute(byte[] buffer)

       {

           return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);

       }

       public static UInt32 Compute(UInt32 seed, byte[] buffer)

       {

           return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);

       }

       public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)

       {

           return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);

       }

       private static UInt32[] InitializeTable(UInt32 polynomial)

       {

           if (polynomial == DefaultPolynomial && defaultTable != null)

           {

               return defaultTable;

           }

           UInt32[] createTable = new UInt32[256];

           for (int i = 0; i < 256; i++)

           {

               UInt32 entry = (UInt32)i;

               for (int j = 0; j < 8; j++)

               {

                   if ((entry & 1) == 1)

                       entry = (entry >> 1) ^ polynomial;

                   else

                       entry = entry >> 1;

               }

               createTable[i] = entry;

           }

           if (polynomial == DefaultPolynomial)

           {

               defaultTable = createTable;

           }

           return createTable;

       }

       private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)

       {

           UInt32 crc = seed;

           for (int i = start; i < size; i++)

           {

               unchecked

               {

                   crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];

               }

           }

           return crc;

       }

       private byte[] UInt32ToBigEndianBytes(UInt32 x)

       {

           return new byte[] { (byte)((x >> 24) & 0xff), (byte)((x >> 16) & 0xff), (byte)((x >> 8) & 0xff), (byte)(x & 0xff) };

       }

   }//end class: Crc32

 

你可能感兴趣的:(hash)