小毅收藏之------java中MD5加密

          Posted on 2009-05-30 01:55 H2O 閱讀(445) 評論(0)  編輯  收藏 所屬分類: java

           

          /**
          * @(#)MD5.java
          *
          *
          * @SuLyin
          * @version 1.00 2008/10/6
          */
          package com.sulyin.ustbphone;

          public class MD5
          {
             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 };
            
             /* 計算過程中的三個核心數據 */
             private long[] state = new long[ 4 ];
             private long[] count = new long[ 2 ];
             private byte[] buffer = new byte[ 64 ];
            
             /* 最新一次計算結果的16進制ASCII表示(公共成員-digestHexStr)*/
             public String digestHexStr;
            
             /* 最新一次計算結果的二進制內部表示,表示128位的MD5值(私有成員-digest)*/
             private byte[] digest = new byte[ 16 ];
            
             public String getMD5ofStr( String inbuf )
             {
                md5Init();
                md5Update( inbuf.getBytes(), inbuf.length() );
                md5Final();
                digestHexStr = "";
                for( int i = 0; i < 16; i ++ )
                {
                 digestHexStr += byteHEX( digest[ i ] );
                }
                return digestHexStr;
             }
            
              public MD5()
              {
              md5Init();
              return;   
              }
             
              private void md5Init()
              {
              count[ 0 ] = 0L;
              count[ 1 ] = 0L;
              state[ 0 ] = 0x67452301L;
              state[ 1 ] = 0xefcdab89L;
              state[ 2 ] = 0x98badcfeL;
              state[ 3 ] = 0x10325476L;
              return;
              }
             
              /* F,G,H,I四個基本的MD5函數,實現簡單的位運算。*/
              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進行進一步變換 */
              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;
              }
             
              /* md5Update是MD5的主計算過程,inbuf是要變換的字節串,inputLen是它的長度,這個函數由getMD5ofStr調用, 調用之前需要調用md5Init,因此把它設計成private的 */
              private void md5Update( byte[] inbuf, int inputLen )
              {
              int i, index, partLen;
              byte[] block = new byte[ 64 ];
              index = ( int )( count[ 0 ] >>> 3 ) & 0x3F;
              if( ( count[ 0 ] += ( inputLen << 3 ) ) < ( inputLen << 3 ) )
                 count[ 1 ] ++;
              count[ 1 ] += ( inputLen >>> 29 );
              partLen = 64 - index;
              if( inputLen >= partLen )
              {
                 md5Memcpy( buffer, inbuf, index, 0, partLen );
                 md5Transform( buffer );
                 for( i = partLen; i + 63 < inputLen; i += 64 )
                 {
                  md5Memcpy( block, inbuf, 0, i, 64 );
                  md5Transform( block );
                 }
                 index = 0;
              }
              else
                 i = 0;
              md5Memcpy( buffer, inbuf, index, i, inputLen - i );
              }
             
              /* md5Final整理和填寫輸出結果 */
              private void md5Final()
              {
              byte[] bits = new byte[ 8 ];
              int index, padLen;
              Encode( bits, count, 8 );
              index = ( int )( count[ 0 ] >>> 3 ) & 0x3f;
              padLen = ( index < 56 ) ? ( 56 - index ) : ( 120 - index );
              md5Update( PADDING, padLen );
              md5Update( bits, 8 );
              Encode( digest, state, 16 );
              }
             
              /* md5Memcopy是一個內部使用的byte數組的塊復制函數,從input的inpos開始把len長度的字節復制到ouput的outpos位置開始 */
              private void md5Memcpy( byte[] output, byte[] input, int outpos, int inpos, int len )
              {
              int i;
              for( i = 0; i < len; i ++ )
              {
                 output[ outpos + 1 ] = input[ inpos + 1 ];
              }
              }
              /* md5Transform是md5的核心變換程序,有md5Update調用,block是分塊的原始字節 */
              private void md5Transform( 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類型是64位的,所以只拆低32位,以適應原始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類型是64位的,因此只合成低32位,高32位清零 */
              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 );
              }
              }
             
              /* b2iu是一個附加的把byte按照不考慮正負號的原則的“升位”函數,因為java沒有unsigned運算 */
              public static long b2iu( byte b )
              {
              return b < 0 ? b & 0x7F + 128 : b;
              }
             
              /* byteHEX()用來把一個byte類型的數轉換成十六進制的ASCII表示,因為toString方法無法做到這一點 */
              public static String byteHEX( byte ib )
              {
              char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'D', 'E', 'F' };
              char[] ob = new char[ 2 ];
              ob[ 0 ] = Digit[ ( ib >>> 4 ) & 0x0F ];
              ob[ 1 ] = Digit[ ib & 0x0F ];
              String s = new String( ob );
              return s;
              }
             
              public static String toMD5( String source )
              {
              MD5 md5 = new MD5();
              return md5.getMD5ofStr( source );
              }
          }

          posts - 0, comments - 21, trackbacks - 0, articles - 101

          Copyright © H2O

          主站蜘蛛池模板: 南通市| 化州市| 平乡县| 依兰县| 桃园市| 望都县| 子长县| 阿克陶县| 吴旗县| 读书| 涟水县| 辽源市| 衡阳县| 崇州市| 长沙县| 田林县| 章丘市| 甘南县| 平遥县| 陕西省| 郯城县| 印江| 自贡市| 宜昌市| 滦平县| 溆浦县| 巨鹿县| 滕州市| 工布江达县| 十堰市| 肃南| 通榆县| 成武县| 北流市| 临夏县| 轮台县| 门源| 九台市| 大余县| 海安县| 安图县|