哪位兄弟有啊?

解决方案 »

  1.   


    /* 
    Copyright 2002 Blood ([email protected])This code is ported from Norbert Hranitzky@#s 
    ([email protected])
    Java version.
    *///reference Namespace
    using System;
    using System.Text;namespace Blood.COM.Security
    {    /// <summary>
        /// Implements the MD4 message digest algorithm in C#
        /// </summary>
        public class MD4
        {
            
            // MD4 specific object variables
            //-----------------------------------------------------------------------
        
            /// <summary>
            /// The size in bytes of the input block to the transformation algorithm
            /// </summary>
            private const int BLOCK_LENGTH = 64;        // = 512 / 8        /// <summary>
            /// 4 32-bit words (interim result)
            /// </summary>
            private uint[] context = new uint[4];        /// <summary>
            /// Number of bytes procesed so far mod. 2 power of 64.
            /// </summary>
            private long count;        /// <summary>
            /// 512-bit input buffer = 16 x 32-bit words holds until it reaches 512 bits
            /// </summary>
            private byte[] buffer = new byte[BLOCK_LENGTH];        /// <summary>
            /// 512-bit work buffer = 16 x 32-bit words
            /// </summary>
            private uint[] X = new uint[16];    
            // Constructors
            //------------------------------------------------------------------------        public MD4()
            {
               engineReset();
            }        /// <summary>
            /// This constructor is here to implement the clonability of this class
            /// </summary>
            /// <param name="md"> </param>
            private MD4(MD4 md): this()
            {
                //this();
                context = (uint[])md.context.Clone();
                buffer = (byte[])md.buffer.Clone();
                count = md.count;
            }        // Clonable method implementation
            //-------------------------------------------------------------------------
            public object Clone() 
            {
                return new MD4(this);
            }        // JCE methods
            //-------------------------------------------------------------------------        /// <summary>
            /// Resets this object disregarding any temporary data present at the
            /// time of the invocation of this call.
            /// </summary>
            private void engineReset()
            {
                // initial values of MD4 i.e. A, B, C, D
                // as per rfc-1320; they are low-order byte first
                context[0] = 0x67452301;
                context[1] = 0xEFCDAB89;
                context[2] = 0x98BADCFE;
                context[3] = 0x10325476;
                count = 0L;
                for(int i = 0; i < BLOCK_LENGTH; i++)
                {
                    buffer[i] = 0;
                }
            }        
            /// <summary>
            /// Continues an MD4 message digest using the input byte
            /// </summary>
            /// <param name="b">byte to input</param>
            private void engineUpdate(byte b)
            {
                // compute number of bytes still unhashed; ie. present in buffer
                int i = (int)(count % BLOCK_LENGTH);
                count++;            // update number of bytes
                buffer[i] = b;
                if(i == BLOCK_LENGTH - 1)
                    transform(ref buffer, 0);
            }        /// <summary>
            /// MD4 block update operation
            /// </summary>
            /// <res>
            /// Continues an MD4 message digest operation by filling the buffer, 
            /// transform(ing) data in 512-bit message block(s), updating the variables
            /// context and count, and leaving (buffering) the remaining bytes in buffer
            /// for the next update or finish.
            /// </res>
            /// <param name="input">input block</param>
            /// <param name="offset">start of meaningful bytes in input</param>
            /// <param name="len">count of bytes in input blcok to consider</param>
            private void engineUpdate(byte[] input, int offset, int len)
            {
                // make sure we don@#t exceed input@#s allocated size/length
                if(offset < 0 || len < 0 || (long)offset + len > input.Length)
                {
                    throw new ArgumentOutOfRangeException();
                }            // compute number of bytes still unhashed; ie. present in buffer
                int bufferNdx = (int)(count % BLOCK_LENGTH);
                count += len;        // update number of bytes
                int partLen = BLOCK_LENGTH - bufferNdx;
                int i = 0;
                if(len >= partLen)
                {
                    Array.Copy(input, offset + i, buffer, bufferNdx, partLen);                transform(ref buffer, 0);                for(i = partLen; i + BLOCK_LENGTH - 1 < len; i+= BLOCK_LENGTH)
                    {
                        transform(ref input, offset + i);
                    }
                    bufferNdx = 0;
                }
                // buffer remaining input
                if(i < len)
                {
                    Array.Copy(input, offset + i, buffer, bufferNdx, len - i);
                }
            }
            
            /// <summary>
            /// Completes the hash computation by performing final operations such
            /// as padding.  At the return of this engineDigest, the MD engine is
            /// reset.
            /// </summary>
            /// <returns>the array of bytes for the resulting hash value.</returns>
            private byte[] engineDigest()
            {
                // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512
                int bufferNdx = (int)(count % BLOCK_LENGTH);
                int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx);            // padding is always binary 1 followed by binary 0@#s
                byte[] tail = new byte[padLen + 8];
                tail[0] = (byte)0x80;            // append length before final transform
                // save number of bits, casting the long to an array of 8 bytes
                // save low-order byte first.
                for(int i = 0; i < 8 ; i++)
                {
                    tail[padLen + i] = (byte)((count * 8) >> (8 * i));
                }            engineUpdate(tail, 0, tail.Length);            byte[] result = new byte[16];
                // cast this MD4@#s context (array of 4 uints) into an array of 16 bytes.
                for(int i = 0;i < 4; i++)
                {
                    for(int j = 0; j < 4; j++)
                    {
                        result[i * 4 + j] = (byte)(context[i] >> (8 * j));
                    }
                }            // reset the engine
                engineReset();
                return result;
            }
      

  2.   

            /// <summary>
            /// Returns a byte hash from a string
            /// </summary>
            /// <param name="s">string to hash</param>
            /// <returns>byte-array that contains the hash</returns>
            public byte[] GetByteHashFromString(string s)
            {
                byte[] b = Encoding.UTF8.GetBytes(s);
                MD4 md4 = new MD4();            md4.engineUpdate(b, 0, b.Length);            return md4.engineDigest();
            }        /// <summary>
            /// Returns a binary hash from an input byte array
            /// </summary>
            /// <param name="b">byte-array to hash</param>
            /// <returns>binary hash of input</returns>
            public byte[] GetByteHashFromBytes(byte[] b)
            {
                MD4 md4 = new MD4();
        
                md4.engineUpdate(b, 0, b.Length);            return md4.engineDigest();
            }        /// <summary>
            /// Returns a string that contains the hexadecimal hash
            /// </summary>
            /// <param name="b">byte-array to input</param>
            /// <returns>String that contains the hex of the hash</returns>
            public string GetHexHashFromBytes(byte[] b)
            {
                byte[] e = GetByteHashFromBytes(b);
                return bytesToHex(e, e.Length);
            }        /// <summary>
            /// Returns a byte hash from the input byte
            /// </summary>
            /// <param name="b">byte to hash</param>
            /// <returns>binary hash of the input byte</returns>
            public byte[] GetByteHashFromByte(byte b)
            {
                MD4 md4 = new MD4();            md4.engineUpdate(b);            return md4.engineDigest();
            }        /// <summary>
            /// Returns a string that contains the hexadecimal hash
            /// </summary>
            /// <param name="b">byte to hash</param>
            /// <returns>String that contains the hex of the hash</returns>
            public string GetHexHashFromByte(byte b)
            {
                byte[] e = GetByteHashFromByte(b);
                return bytesToHex(e, e.Length);
            }        /// <summary>
            /// Returns a string that contains the hexadecimal hash
            /// </summary>
            /// <param name="s">string to hash</param>
            /// <returns>String that contains the hex of the hash</returns>
            public string GetHexHashFromString(string s)
            {
                byte[] b = GetByteHashFromString(s);
                return bytesToHex(b, b.Length);
            }        private static string bytesToHex(byte[] a, int len)
            {
                string temp = BitConverter.ToString(a);
        
                // We need to remove the dashes that come from the BitConverter
                StringBuilder sb = new StringBuilder((len - 2) / 2);    // This should be the final size            for(int i = 0; i < temp.Length ; i++)
                {
                    if(temp[i] != @#-@#)
                    {
                        sb.Append(temp[i]);
                    }
                }            return sb.ToString();
            }        // own methods
            //-----------------------------------------------------------------------------------        /// <summary>
            /// MD4 basic transformation
            /// </summary>
            /// <res>
            /// Transforms context based on 512 bits from input block starting
            /// from the offset@#th byte.
            /// </res>
            /// <param name="block">input sub-array</param>
            /// <param name="offset">starting position of sub-array</param>
            private void transform(ref byte[] block, int offset)
            {
                // decodes 64 bytes from input block into an array of 16 32-bit
                // entities. Use A as a temp var.
                for (int i = 0; i < 16; i++)
                {
                    X[i] = ((uint)block[offset++] & 0xFF)     |
                        (((uint)block[offset++] & 0xFF) <<  8)   |
                        (((uint)block[offset++] & 0xFF) <<  16)  |
                        (((uint)block[offset++] & 0xFF) <<  24);
                }
                uint A = context[0];
                uint B = context[1];
                uint C = context[2];
                uint D = context[3];            A = FF(A, B, C, D, X[ 0],  3);
                D = FF(D, A, B, C, X[ 1],  7);
                C = FF(C, D, A, B, X[ 2], 11);
                B = FF(B, C, D, A, X[ 3], 19);
                A = FF(A, B, C, D, X[ 4],  3);
                D = FF(D, A, B, C, X[ 5],  7);
                C = FF(C, D, A, B, X[ 6], 11);
                B = FF(B, C, D, A, X[ 7], 19);
                A = FF(A, B, C, D, X[ 8],  3);
                D = FF(D, A, B, C, X[ 9],  7);
                C = FF(C, D, A, B, X[10], 11);
                B = FF(B, C, D, A, X[11], 19);
                A = FF(A, B, C, D, X[12],  3);
                D = FF(D, A, B, C, X[13],  7);
                C = FF(C, D, A, B, X[14], 11);
                B = FF(B, C, D, A, X[15], 19);            A = GG(A, B, C, D, X[ 0],  3);
                D = GG(D, A, B, C, X[ 4],  5);
                C = GG(C, D, A, B, X[ 8],  9);
                B = GG(B, C, D, A, X[12], 13);
                A = GG(A, B, C, D, X[ 1],  3);
                D = GG(D, A, B, C, X[ 5],  5);
                C = GG(C, D, A, B, X[ 9],  9);
                B = GG(B, C, D, A, X[13], 13);
                A = GG(A, B, C, D, X[ 2],  3);
                D = GG(D, A, B, C, X[ 6],  5);
                C = GG(C, D, A, B, X[10],  9);
                B = GG(B, C, D, A, X[14], 13);
                A = GG(A, B, C, D, X[ 3],  3);
                D = GG(D, A, B, C, X[ 7],  5);
                C = GG(C, D, A, B, X[11],  9);
                B = GG(B, C, D, A, X[15], 13);            A = HH(A, B, C, D, X[ 0],  3);
                D = HH(D, A, B, C, X[ 8],  9);
                C = HH(C, D, A, B, X[ 4], 11);
                B = HH(B, C, D, A, X[12], 15);
                A = HH(A, B, C, D, X[ 2],  3);
                D = HH(D, A, B, C, X[10],  9);
                C = HH(C, D, A, B, X[ 6], 11);
                B = HH(B, C, D, A, X[14], 15);
                A = HH(A, B, C, D, X[ 1],  3);
                D = HH(D, A, B, C, X[ 9],  9);
                C = HH(C, D, A, B, X[ 5], 11);
                B = HH(B, C, D, A, X[13], 15);
                A = HH(A, B, C, D, X[ 3],  3);
                D = HH(D, A, B, C, X[11],  9);
                C = HH(C, D, A, B, X[ 7], 11);
                B = HH(B, C, D, A, X[15], 15);            context[0] += A;
                context[1] += B;
                context[2] += C;
                context[3] += D;
            }        // The basic MD4 atomic functions.        private uint FF(uint a, uint b, uint c, uint d, uint x, int s)
            {
                uint t = a + ((b & c) | (~b & d)) + x;
                return t << s | t >> (32 - s);
            }
            private uint GG(uint a, uint b, uint c, uint d, uint x, int s)
            {
                uint t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999;
                return t << s | t >> (32 - s);
            }
            private uint HH(uint a, uint b, uint c, uint d, uint x, int s)
            {
                uint t = a + (b ^ c ^ d) + x + 0x6ED9EBA1;
                return t << s | t >> (32 - s);
            }    } // class MD4
    } // namespace Blood.COM.Security
      

  3.   

    都发完了,晕
    我也找有一个一模一样的,Google上找的