调试了很久了,还是找不出根源。希望大家能够帮忙一下,二十分感谢。
我剩下的分数不多,希望大家见谅。
//Create function array
interface FunctionArrayInterface {
        int runIt(int X, int Y, int Z);
}// fM, gM, hM and iM are basic MD5 methods.
class F implements FunctionArrayInterface {
        public int runIt(int X, int Y, int Z) {
                return (X & Y) | (~X & Z);
        }}class G implements FunctionArrayInterface {
        public int runIt(int X, int Y, int Z) {
                return (X & Z) | (Y & ~Z);
        }
}class H implements FunctionArrayInterface {
        public int runIt(int X, int Y, int Z) {
                return X ^ Y ^ Z;
        }
}class I implements FunctionArrayInterface {
        public int runIt(int X, int Y, int Z) {
                return Y ^ (X | ~Z);
        }
}
/** 这是MD5的主要算法, 本算法只对字符串的MD5值进行计算 */
public class MD5 {        private static final byte SINGLE_ONE_BIT = (byte) 0X80;
        private static final short BLOCK_SIZE = 512;
        private static final short MOD_SIZE = 448;
        private static final short APP_SIZE = 64;
        private static final short BITS = 8;
        // 定义四个主要参数
        private static final int A = 0x67452301;
        private static final int B = 0xEFCDAB89;
        private static final int C = 0x98BADCFE;
        private static final int D = 0x10325476;
        // Constants for MD5 transform routine.
        private static final byte X[][] = { { 0, 1 }, { 1, 5 }, { 5, 3 }, { 0, 7 } };
        private static final byte S[][] = { { 7, 12, 17, 22 }, { 5, 9, 14, 20 },
                        { 4, 11, 16, 23 }, { 6, 10, 15, 21 } };        // rotates x left s bits
        static int rotateLeft(int x, int s) {
                return (x << s) | (x >>> (32 - s));
        }        // 计算要进行补位的位数
        static int conutPaddingBits(int length) {
                int mod = length * BITS % BLOCK_SIZE;
                int cBits;                if (mod == 0) {
                        cBits = MOD_SIZE;
                } else {
                        cBits = (MOD_SIZE + BLOCK_SIZE - mod) % BLOCK_SIZE;
                }                return cBits / BITS;
        }        // 对字符串进行补位
        static byte[] appendPaddingBits(String argv) {
                int msgLength = argv.length();
                int bitLength = conutPaddingBits(msgLength);
                long appLength = msgLength * BITS;
                char[] temp = argv.toCharArray();
                byte[] message = new byte[(int) (msgLength + bitLength + APP_SIZE / 8)];                try {
                        for (int i = 0; i < msgLength; i++) {
                                message[i] = (byte) temp[i];
                        }
                        for (int i = 1; i < bitLength; i++) {
                                message[(int) (msgLength + i)] = 0;
                        }
                        message[(int) msgLength] = SINGLE_ONE_BIT;                        // Append length (before padding).
                        long tmpLength = appLength;
                        for (int i = 0; i < 8; i++) {
                                message[(int) (msgLength + bitLength + i)] = (byte) (tmpLength >>> ((7 - i) * 8));
                        }
                } catch (IndexOutOfBoundsException evt) {
                        System.out.println(evt.getMessage());
                }
                return message;
        }        // 计算字符串的MD5值的主要算法
        static String calculateMD5(String message) {
                FunctionArrayInterface[] auxi = new FunctionArrayInterface[4];
                auxi[0] = new F();
                auxi[1] = new G();
                auxi[2] = new H();
                auxi[3] = new I();
                int[] chain = { A, B, C, D };
                byte[] result = appendPaddingBits(message);
                int[] temp = new int[16];                for (int k = 0; k < result.length; k += BLOCK_SIZE / BITS) {
                        int[] state = { A, B, C, D };                        for (int i = 0; i < 16; i++) {
                                temp[i] = ((int) (result[k + i * 4 + 0] & 0xFF) << 24)
                                                | ((int) (result[k + i * 4 + 1] & 0xFF) << 16)
                                                | ((int) (result[k + i * 4 + 2] & 0xFF) << 8)
                                                | ((int) result[k + i * 4 + 3] & 0xFF);
                        }                        for (int roundIdx = 0, sIdx, wIdx; roundIdx < 4; roundIdx++) {
                                wIdx = X[roundIdx][0];
                                sIdx = 0;                                for (int i = 0; i < 16; i++) {
                                        // FF, GG, HH, and II transformations for rounds 1, 2, 3,
                                        // and 4.
                                        // Rotation is separate from addition to prevent
                                        // recomputation.
                                        state[sIdx] = state[(sIdx + 1) % 4]
                                                        + rotateLeft(
                                                                        (int) (state[sIdx]
                                                                                        + auxi[roundIdx].runIt(
                                                                                                        state[(sIdx + 1) % 4],
                                                                                                        state[(sIdx + 2) % 4],
                                                                                                        state[(sIdx + 3) % 4])
                                                                                        + temp[wIdx] + (int) (Math.floor((0x40000000 * 4)
                                                                                        * Math.abs(Math.sin(roundIdx * 16
                                                                                                        + i + 1))))),
                                                                        S[roundIdx][i % 4]);
                                        sIdx = (sIdx + 3) % 4;
                                        wIdx = (wIdx + X[roundIdx][1]) & 0x0F;
                                }
                        }                        chain[0] += state[0];
                        chain[1] += state[1];
                        chain[2] += state[2];
                        chain[3] += state[3];
                }                StringBuffer buf = new StringBuffer();
                char[] bits = "0123456789ABCDEF".toCharArray();
                for (int i = 0; i < 4; i++) {
                        for (int j = 0; j < 8; j++) {
                                buf.append(bits[(int) (chain[i] >>> ((7 - j) * 4) & 0x0F)]);
                        }
                }
                return buf.toString();
        }        public static void main(String[] args) {
                String input = " ";
                String result = MD5.calculateMD5(input);
                System.out.println(result);
        }
}

解决方案 »

  1.   

    百度上的C语言实现代码如下:
    /*
    * md5 -- compute and check MD5 message digest.
    * this version only can calculate the char string.
    *
    * MD5 (Message-Digest algorithm 5) is a widely used, partially
    * insecure cryptographic hash function with a 128-bit hash value.
    *
    * Author: redraiment
    * Date: Aug 27, 2008
    * Version: 0.1.6
    */
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    #define SINGLE_ONE_BIT 0x80
    #define BLOCK_SIZE 512
    #define MOD_SIZE 448
    #define APP_SIZE 64
    #define BITS 8
    // MD5 Chaining Variable
    #define A 0x67452301UL
    #define B 0xEFCDAB89UL
    #define C 0x98BADCFEUL
    #define D 0x10325476UL
    // Creating own types
    #ifdef UINT64
    # undef UINT64
    #endif
    #ifdef UINT32
    # undef UINT32
    #endif
    typedef unsigned long long UINT64;
    typedef unsigned long UINT32;
    typedef unsigned char UINT8;
    typedef struct
    {
        char * message;
        UINT64 length;
    }STRING;
    const UINT32 X[4][2] = {{0, 1}, {1, 5}, {5, 3}, {0, 7}};
    // Constants for MD5 transform routine.
    const UINT32 S[4][4] = {
        { 7, 12, 17, 22 },
        { 5, 9, 14, 20 },
        { 4, 11, 16, 23 },
        { 6, 10, 15, 21 }
    };
    // F, G, H and I are basic MD5 functions.
    UINT32 F( UINT32 X, UINT32 Y, UINT32 Z )
    {
        return ( X & Y ) | ( ~X & Z );
    }
    UINT32 G( UINT32 X, UINT32 Y, UINT32 Z )
    {
        return ( X & Z ) | ( Y & ~Z );
    }
    UINT32 H( UINT32 X, UINT32 Y, UINT32 Z )
    {
        return X ^ Y ^ Z;
    }
    UINT32 I( UINT32 X, UINT32 Y, UINT32 Z )
    {
        return Y ^ ( X | ~Z );
    }
    // rotates x left s bits.
    UINT32 rotate_left( UINT32 x, UINT32 s )
    {
        return ( x << s ) | ( x >> ( 32 - s ) );
    }
    // Pre-processin
    UINT32 count_padding_bits ( UINT32 length )
    {
        UINT32 div = length * BITS / BLOCK_SIZE;
        UINT32 mod = length * BITS % BLOCK_SIZE;
        UINT32 c_bits;
        if ( mod == 0 )
            c_bits = MOD_SIZE;
        else
            c_bits = ( MOD_SIZE + BLOCK_SIZE - mod ) % BLOCK_SIZE;
        return c_bits / BITS;
    }
    STRING append_padding_bits ( char * argv )
    {
        UINT32 msg_length = strlen ( argv );
        UINT32 bit_length = count_padding_bits ( msg_length );
        UINT64 app_length = msg_length * BITS;
        STRING string;
        string.message = (char *)malloc(msg_length + bit_length + APP_SIZE / BITS);
        // Save message
        strncpy ( string.message, argv, msg_length );
        // Pad out to mod 64.
        memset ( string.message + msg_length, 0, bit_length );
        string.message [ msg_length ] = SINGLE_ONE_BIT;
        // Append length (before padding).
        memmove ( string.message + msg_length + bit_length, (char *)&app_length, sizeof( UINT64 ) );
        string.length = msg_length + bit_length + sizeof( UINT64 );
        return string;
    }int main ( int argc, char *argv[] )
    {
        STRING string;
        UINT32 w[16];
        UINT32 chain[4];
        UINT32 state[4];
        UINT8 r[16];
        UINT32 ( *auxi[ 4 ])( UINT32, UINT32, UINT32 ) = { F, G, H, I };
        int roundIdx;
        int argIdx;
        int sIdx;
        int wIdx;
        int i;
        int j;
        if ( argc < 2 )
        {
            fprintf ( stderr, "usage: %s string ...\n", argv[ 0 ] );
            return EXIT_FAILURE;
        }
        for ( argIdx = 1; argIdx < argc; argIdx++ )
        {
            string = append_padding_bits ( argv[ argIdx ] );
            // MD5 initialization.
            chain[0] = A;
            chain[1] = B;
            chain[2] = C;
            chain[3] = D;
            for ( j = 0; j < string.length; j += BLOCK_SIZE / BITS)
            {
                memmove ( (char *)w, string.message + j, BLOCK_SIZE / BITS );
                memmove ( state, chain, sizeof(chain) );
                for ( roundIdx = 0; roundIdx < 4; roundIdx++ )
                {
                    wIdx = X[ roundIdx ][ 0 ];
                    sIdx = 0;
                    for ( i = 0; i < 16; i++ )
                    {
                        // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
                        // Rotation is separate from addition to prevent recomputation.
                        state[sIdx] = state [ (sIdx + 1) % 4 ] + 
                                rotate_left ( state[sIdx] + 
                                ( *auxi[ roundIdx ] )
                                ( state[(sIdx+1) % 4], state[(sIdx+2) % 4], state[(sIdx+3) % 4]) +
                                w[ wIdx ] +
                                (UINT32)floor( (1ULL << 32) * fabs(sin( roundIdx * 16 + i + 1 )) ),
                                S[ roundIdx ][ i % 4 ]);
                        sIdx = ( sIdx + 3 ) % 4;
                        wIdx = ( wIdx + X[ roundIdx ][ 1 ] ) & 0xF;
                    }
                }
                chain[ 0 ] += state[ 0 ];
                chain[ 1 ] += state[ 1 ];
                chain[ 2 ] += state[ 2 ];
                chain[ 3 ] += state[ 3 ];
            }
            memmove ( r + 0, (char *)&chain[0], sizeof(UINT32) );
            memmove ( r + 4, (char *)&chain[1], sizeof(UINT32) );
            memmove ( r + 8, (char *)&chain[2], sizeof(UINT32) );
            memmove ( r + 12, (char *)&chain[3], sizeof(UINT32) );
            for ( i = 0; i < 16; i++ )
                printf ( "%02x", r[i] );
            putchar ( '\n' );
        }
        return EXIT_SUCCESS;
      

  2.   


    private static void Md5(String plainText ) {
      try {
       MessageDigest md = MessageDigest.getInstance("MD5");   
       md.update(plainText.getBytes());
       byte b[] = md.digest();   int i;
       
       StringBuffer buf = new StringBuffer(""); 
       for (int offset = 0; offset < b.length; offset++) {
        i = b[offset];
        if(i<0) i+= 256;
        if(i<16)
         buf.append("0");
        buf.append(Integer.toHexString(i));
       }   System.out.println("result: " + buf.toString());//32位的加密   System.out.println("result: " + buf.toString().substring(8,24));//16位的加密  } catch (NoSuchAlgorithmException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
      

  3.   


    import java.lang.reflect.*;/*******************************************************************************
     * keyBean 类实现了RSA Data Security, Inc.在提交给IETF 的RFC1321中的keyBean message-digest
     * 算法。
     ******************************************************************************/
    public class keyBean {
        /*
         * 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, 这里把它们实现成为static
         * final是表示了只读,切能在同一个进程空间内的多个 Instance间共享
         */
        static final int S11 = 7;    static final int S12 = 12;    static final int S13 = 17;    static final int S14 = 22;    static final int S21 = 5;    static final int S22 = 9;    static final int S23 = 14;    static final int S24 = 20;    static final int S31 = 4;    static final int S32 = 11;    static final int S33 = 16;    static final int S34 = 23;    static final int S41 = 6;    static final int S42 = 10;    static final int S43 = 15;    static final int S44 = 21;    static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0 };    /*
         * 下面的三个成员是keyBean计算过程中用到的3个核心数据,在原始的C实现中 被定义到keyBean_CTX结构中
         */
        private long[] state = new long[4]; // state (ABCD)    private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb    // first)    private byte[] buffer = new byte[64]; // input buffer    /*
         * digestHexStr是keyBean的唯一一个公共成员,是最新一次计算结果的 16进制ASCII表示.
         */    public String digestHexStr;    /*
         * digest,是最新一次计算结果的2进制内部表示,表示128bit的keyBean值.
         */
        private byte[] digest = new byte[16];    /*
         * getkeyBeanofStr是类keyBean最主要的公共方法,入口参数是你想要进行keyBean变换的字符串
         * 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.
         */
        public String getkeyBeanofStr(String inbuf) {
            keyBeanInit();
            keyBeanUpdate(inbuf.getBytes(), inbuf.length());
            keyBeanFinal();
            digestHexStr = "";
            for (int i = 0; i < 16; i++) {
                digestHexStr += byteHEX(digest[i]);
            }
            return digestHexStr;
        }    // 这是keyBean这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数
        public keyBean() {
            keyBeanInit();
            return;
        }    /* keyBeanInit是一个初始化函数,初始化核心变量,装入标准的幻数 */
        private void keyBeanInit() {
            count[0] = 0L;
            count[1] = 0L;
            // /* Load magic initialization constants.
            state[0] = 0x67452301L;
            state[1] = 0xefcdab89L;
            state[2] = 0x98badcfeL;
            state[3] = 0x10325476L;
            return;
        }    /*
         * F, G, H ,I 是4个基本的keyBean函数,在原始的keyBean的C实现中,由于它们是
         * 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们 实现成了private方法,名字保持了原来C中的。
         */
        private long F(long x, long y, long z) {
            return (x & y) | ((~x) & z);
        }    private long G(long x, long y, long z) {
            return (x & z) | (y & (~z));
        }    private long H(long x, long y, long z) {
            return x ^ y ^ z;
        }    private long I(long x, long y, long z) {
            return y ^ (x | (~z));
        }    /*
         * FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for
         * rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent
         * recomputation.
         */
        private long FF(long a, long b, long c, long d, long x, long s, long ac) {
            a += F(b, c, d) + x + ac;
            a = ((int) a << s) | ((int) a >>> (32 - s));
            a += b;
            return a;
        }    private long GG(long a, long b, long c, long d, long x, long s, long ac) {
            a += G(b, c, d) + x + ac;
            a = ((int) a << s) | ((int) a >>> (32 - s));
            a += b;
            return a;
        }    private long HH(long a, long b, long c, long d, long x, long s, long ac) {
            a += H(b, c, d) + x + ac;
            a = ((int) a << s) | ((int) a >>> (32 - s));
            a += b;
            return a;
        }    private long II(long a, long b, long c, long d, long x, long s, long ac) {
            a += I(b, c, d) + x + ac;
            a = ((int) a << s) | ((int) a >>> (32 - s));
            a += b;
            return a;
        }    /*
         * keyBeanUpdate是keyBean的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个
         * 函数由getkeyBeanofStr调用,调用之前需要调用keyBeaninit,因此把它设计成private的
         */
        private void keyBeanUpdate(byte[] inbuf, int inputLen) {
            int i, index, partLen;
            byte[] block = new byte[64];
            index = (int) (count[0] >>> 3) & 0x3F;
            // /* Update number of bits */
            if ((count[0] += (inputLen << 3)) < (inputLen << 3))
                count[1]++;
            count[1] += (inputLen >>> 29);
            partLen = 64 - index;
            // Transform as many times as possible.
            if (inputLen >= partLen) {
                keyBeanMemcpy(buffer, inbuf, index, 0, partLen);
                keyBeanTransform(buffer);
                for (i = partLen; i + 63 < inputLen; i += 64) {
                    keyBeanMemcpy(block, inbuf, 0, i, 64);
                    keyBeanTransform(block);
                }
                index = 0;
            } else
                i = 0;
            // /* Buffer remaining input */
            keyBeanMemcpy(buffer, inbuf, index, i, inputLen - i);
        }    /*
         * keyBeanFinal整理和填写输出结果
         */
        private void keyBeanFinal() {
            byte[] bits = new byte[8];
            int index, padLen;
            // /* Save number of bits */
            Encode(bits, count, 8);
            // /* Pad out to 56 mod 64.
            index = (int) (count[0] >>> 3) & 0x3f;
            padLen = (index < 56) ? (56 - index) : (120 - index);
            keyBeanUpdate(PADDING, padLen);
            // /* Append length (before padding) */
            keyBeanUpdate(bits, 8);
            // /* Store state in digest */
            Encode(digest, state, 16);
        }    /*
         * keyBeanMemcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的
         * 字节拷贝到output的outpos位置开始
         */
        private void keyBeanMemcpy(byte[] output, byte[] input, int outpos,
                int inpos, int len) {
            int i;
            for (i = 0; i < len; i++)
                output[outpos + i] = input[inpos + i];
        }  
      

  4.   

    接上帖的  /*
         * keyBeanTransform是keyBean核心变换程序,有keyBeanUpdate调用,block是分块的原始字节
         */
        private void keyBeanTransform(byte block[]) {
            long a = state[0], b = state[1], c = state[2], d = state[3];
            long[] x = new long[16];
            Decode(x, block, 64);
            /* Round 1 */
            a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
            d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
            c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
            b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
            a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
            d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
            c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
            b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
            a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
            d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
            c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
            b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
            a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
            d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
            c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
            b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
            /* Round 2 */
            a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
            d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
            c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
            b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
            a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
            d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
            c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
            b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
            a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
            d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
            c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
            b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
            a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
            d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
            c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
            b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
            /* Round 3 */
            a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
            d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
            c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
            b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
            a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
            d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
            c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
            b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
            a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
            d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
            c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
            b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
            a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
            d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
            c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
            b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
            /* Round 4 */
            a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
            d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
            c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
            b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
            a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
            d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
            c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
            b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
            a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
            d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
            c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
            b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
            a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
            d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
            c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
            b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
            state[0] += a;
            state[1] += b;
            state[2] += c;
            state[3] += d;
        }    /*
         * Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, 只拆低32bit,以适应原始C实现的用途
         */
        private void Encode(byte[] output, long[] input, int len) {
            int i, j;
            for (i = 0, j = 0; j < len; i++, j += 4) {
                output[j] = (byte) (input[i] & 0xffL);
                output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);
                output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);
                output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);
            }
        }    /*
         * Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的,
         * 只合成低32bit,高32bit清零,以适应原始C实现的用途
         */
        private void Decode(long[] output, byte[] input, int len) {
            int i, j;        for (i = 0, j = 0; j < len; i++, j += 4)
                output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8)
                        | (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24);
            return;
        }
      

  5.   

    java有自带的MD5,你怎么自己实现啊