/// <summary> /// Calculate the binary MD5 hash of a binary input /// </summary> /// <param name="input"></param> /// <returns></returns> public static byte[] GetHash(byte[] input) { if (null == input) { throw new System.ArgumentNullException(nameof(input), "Unable to calculate hash over null input data"); } //Intitial values defined in RFC 1321 ABCDStruct abcd = new ABCDStruct(); abcd.A = 0x67452301; abcd.B = 0xefcdab89; abcd.C = 0x98badcfe; abcd.D = 0x10325476; //We pass in the input array by block, the final block of data must be handled specialy for padding & length embeding int startIndex = 0; while (startIndex <= input.Length - 64) { MD5Core.GetHashBlock(input, ref abcd, startIndex); startIndex += 64; } // The final data block. return(MD5Core.GetHashFinalBlock(input, startIndex, input.Length - startIndex, abcd, (Int64)input.Length * 8)); }
/// <summary> /// Calculate a CRC for the provided byte array /// </summary> /// <param name="data"></param> /// <param name="length"></param> /// <returns>A 4 byte CRC value created by calculating an MD5 hash of the provided byte array</returns> public static byte[] CalculateCRC(byte[] data, int length) { if (length < data.Length) { byte[] shortData = new byte[length]; Array.Copy(data, shortData, length); data = shortData; } //to be FIPS compliant we have to not use the Crypto-API version of MD5. byte[] crc = MD5Core.GetHash(data); //This is a big bogus - I'm just going to take the first four bytes. We really should //go find the true CRC32 algorithm return(new byte[4] { crc[0], crc[1], crc[2], crc[3] }); }