1. 程式人生 > >計算hash值

計算hash值

 class 計算hash值
    {
        //計算hash值需要引用系統包:using System.Security.Cryptography;
        //計算分兩步:
        //1. 計算hash:  MD5 calculator = MD5.Create();  
        //               Byte[] buffer = calculator.ComputeHash(fs);==>計算完成後需要釋放(1.使用using  2.完成後執行calculator.Clear();)
        //2. 將位元組陣列轉換成十六進位制的字串形式
        public void ComputeHash()
        {
            string hashMD5 = string.Empty;
            //讀取檔案流
            using (FileStream fs = new FileStream(@"C:\Users\lu.jiang.UNITED-IMAGING\Desktop\ReadMe.txt", FileMode.Open, FileAccess.Read))
            {
                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"));//10和26轉換為16進位制二位數後為:0a  1A
                }
                hashMD5 = stringBuilder.ToString();
            }
            Console.WriteLine(hashMD5);
            Console.ReadKey();
        }
        //注意:如果輸入為字串,計算字串input的hash,需要先轉換為位元組
        //Encoding.UTF8.GetBytes(input)
        /// <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) };
        }
    }