The MD4 Class.(C#)

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
Class="baidu_ad"> /*
Copyright 2002 Blood (eaststarbuy@sina.com)

This code is ported from Norbert Hranitzky's
(norbert.hranitzky@mchp.siemens.de)
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>
        /// <remarks>
        /// 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.
        /// </remarks>
        /// <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;
        }

        /// <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 Ge ThexHashFromBytes(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 Ge ThexHashFromByte(byte b)
        {
            byte[] e = GetByteHashFromByte(b); 共2页: 上一页 1 [2] 下一页 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值