using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace POSV.Common.Util { /// /// MD5算法的3rdParty实现 /// 参考https://github.com/Dozer74/MD5 /// public class LabMD5 { #region Helper private sealed class Digest { public uint A; public uint B; public uint C; public uint D; public Digest() { A = 0x67452301; B = 0xEFCDAB89; C = 0x98BADCFE; D = 0X10325476; } public override string ToString() { string st; st = BitHelper.ReverseByte(A).ToString("x8") + BitHelper.ReverseByte(B).ToString("x8") + BitHelper.ReverseByte(C).ToString("x8") + BitHelper.ReverseByte(D).ToString("x8"); return st; } } private static class BitHelper { /// /// rotate /// /// num /// shift /// public static uint RotateLeft(uint num , ushort shift) { return (num >> (32 - shift)) | (num << shift); } /// /// reverse /// public static uint ReverseByte(uint num) { return ((num & 0x000000ff) << 24) | (num >> 24) | ((num & 0x00ff0000) >> 8) | ((num & 0x0000ff00) << 8); } } #endregion Helper #region Table /// /// table 4294967296*sin(i) /// private static readonly uint[] T = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; #endregion Table private uint[] X = new uint[16]; /// /// ComputeHash /// public string ComputeHash(byte[] bytes) { var dg = new Digest(); var bMsg = CreatePaddedBuffer(bytes); var mesLength = (uint)(bMsg.Length * 8) / 32; for (uint i = 0; i < mesLength / 16; i++) { CopyBlock(bMsg , i); Transform(ref dg.A , ref dg.B , ref dg.C , ref dg.D); } return dg.ToString(); } private void Transform(ref uint A , ref uint B , ref uint C , ref uint D) { var AA = A; var BB = B; var CC = C; var DD = D; /* Round 1 */ F(ref A , B , C , D , 0 , 7 , 1); F(ref D , A , B , C , 1 , 12 , 2); F(ref C , D , A , B , 2 , 17 , 3); F(ref B , C , D , A , 3 , 22 , 4); F(ref A , B , C , D , 4 , 7 , 5); F(ref D , A , B , C , 5 , 12 , 6); F(ref C , D , A , B , 6 , 17 , 7); F(ref B , C , D , A , 7 , 22 , 8); F(ref A , B , C , D , 8 , 7 , 9); F(ref D , A , B , C , 9 , 12 , 10); F(ref C , D , A , B , 10 , 17 , 11); F(ref B , C , D , A , 11 , 22 , 12); F(ref A , B , C , D , 12 , 7 , 13); F(ref D , A , B , C , 13 , 12 , 14); F(ref C , D , A , B , 14 , 17 , 15); F(ref B , C , D , A , 15 , 22 , 16); /* Round 2 */ G(ref A , B , C , D , 1 , 5 , 17); G(ref D , A , B , C , 6 , 9 , 18); G(ref C , D , A , B , 11 , 14 , 19); G(ref B , C , D , A , 0 , 20 , 20); G(ref A , B , C , D , 5 , 5 , 21); G(ref D , A , B , C , 10 , 9 , 22); G(ref C , D , A , B , 15 , 14 , 23); G(ref B , C , D , A , 4 , 20 , 24); G(ref A , B , C , D , 9 , 5 , 25); G(ref D , A , B , C , 14 , 9 , 26); G(ref C , D , A , B , 3 , 14 , 27); G(ref B , C , D , A , 8 , 20 , 28); G(ref A , B , C , D , 13 , 5 , 29); G(ref D , A , B , C , 2 , 9 , 30); G(ref C , D , A , B , 7 , 14 , 31); G(ref B , C , D , A , 12 , 20 , 32); /* Round 3 */ H(ref A , B , C , D , 5 , 4 , 33); H(ref D , A , B , C , 8 , 11 , 34); H(ref C , D , A , B , 11 , 16 , 35); H(ref B , C , D , A , 14 , 23 , 36); H(ref A , B , C , D , 1 , 4 , 37); H(ref D , A , B , C , 4 , 11 , 38); H(ref C , D , A , B , 7 , 16 , 39); H(ref B , C , D , A , 10 , 23 , 40); H(ref A , B , C , D , 13 , 4 , 41); H(ref D , A , B , C , 0 , 11 , 42); H(ref C , D , A , B , 3 , 16 , 43); H(ref B , C , D , A , 6 , 23 , 44); H(ref A , B , C , D , 9 , 4 , 45); H(ref D , A , B , C , 12 , 11 , 46); H(ref C , D , A , B , 15 , 16 , 47); H(ref B , C , D , A , 2 , 23 , 48); /* Round 4 */ I(ref A , B , C , D , 0 , 6 , 49); I(ref D , A , B , C , 7 , 10 , 50); I(ref C , D , A , B , 14 , 15 , 51); I(ref B , C , D , A , 5 , 21 , 52); I(ref A , B , C , D , 12 , 6 , 53); I(ref D , A , B , C , 3 , 10 , 54); I(ref C , D , A , B , 10 , 15 , 55); I(ref B , C , D , A , 1 , 21 , 56); I(ref A , B , C , D , 8 , 6 , 57); I(ref D , A , B , C , 15 , 10 , 58); I(ref C , D , A , B , 6 , 15 , 59); I(ref B , C , D , A , 13 , 21 , 60); I(ref A , B , C , D , 4 , 6 , 61); I(ref D , A , B , C , 11 , 10 , 62); I(ref C , D , A , B , 2 , 15 , 63); I(ref B , C , D , A , 9 , 21 , 64); A = A + AA; B = B + BB; C = C + CC; D = D + DD; } private byte[] CreatePaddedBuffer(byte[] mes) { var padSize = 448 - mes.Length * 8 % 512; var pad = (uint)((padSize + 512) % 512); if (pad == 0) pad = 512; var sizeMsgBuff = (uint)(mes.Length + pad / 8 + 8); var sizeMsg = (ulong)mes.Length * 8; var bMsg = new byte[sizeMsgBuff]; for (var i = 0; i < mes.Length; i++) bMsg[i] = mes[i]; bMsg[mes.Length] |= 0x80; for (var i = 8; i > 0; i--) bMsg[sizeMsgBuff - i] = (byte)((sizeMsg >> ((8 - i) * 8)) & 0x00000000000000ff); return bMsg; } private void CopyBlock(byte[] bMsg , uint block) { block = block << 6; for (uint j = 0; j < 61; j += 4) X[j >> 2] = ((uint)bMsg[block + j + 3] << 24) | ((uint)bMsg[block + j + 2] << 16) | ((uint)bMsg[block + j + 1] << 8) | bMsg[block + j]; } #region Transform private void F(ref uint a , uint b , uint c , uint d , uint k , ushort s , uint i) { a = b + BitHelper.RotateLeft(a + ((b & c) | (~b & d)) + X[k] + T[i - 1] , s); } private void G(ref uint a , uint b , uint c , uint d , uint k , ushort s , uint i) { a = b + BitHelper.RotateLeft(a + ((b & d) | (c & ~d)) + X[k] + T[i - 1] , s); } private void H(ref uint a , uint b , uint c , uint d , uint k , ushort s , uint i) { a = b + BitHelper.RotateLeft(a + (b ^ c ^ d) + X[k] + T[i - 1] , s); } private void I(ref uint a , uint b , uint c , uint d , uint k , ushort s , uint i) { a = b + BitHelper.RotateLeft(a + (c ^ (b | ~d)) + X[k] + T[i - 1] , s); } #endregion Transform } }