调试了很久了,还是找不出根源。希望大家能够帮忙一下,二十分感谢。
我剩下的分数不多,希望大家见谅。
//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);
}
}
我剩下的分数不多,希望大家见谅。
//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);
}
}
/*
* 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;
}
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();
}
}
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];
}
* 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;
}