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;
// MD5 Chaining Variable
private static final long A = 0x67452301L;
private static final long B = 0xEFCDAB89L;
private static final long C = 0x98BADCFEL;
private static final long D = 0x10325476L;
// 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 long rotateLeft ( long x, long s){
return ( (int)x << s) | (( (int)x ) >>> ( 32 - s));
}
// Pre-processing
static long conutPaddingBits( long length){
long mod = length * BITS % BLOCK_SIZE;
long cBits;
if ( mod == 0){
cBits = MOD_SIZE;
} else {
cBits = ( MOD_SIZE + BLOCK_SIZE - mod) % BLOCK_SIZE;
}
return cBits / BITS;
}
static byte [] appendPaddingBits( String argv){
long msgLength = argv.length();
long bitLength = conutPaddingBits ( msgLength);
long appLength = msgLength * BITS;
char []temp = argv.toCharArray();
byte []message = new byte[(int) (msgLength + bitLength + APP_SIZE / 8)];
try{
// Save message
//argv.getChars(0, (int) msgLength, temp, 0);
// Pad out to mod 64.
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).
byte []length = longToCharArray( appLength);
for ( int i = 0; i < 8; i++) {
message[ (int) (msgLength + bitLength + i)] = length[i];
}
} catch ( IndexOutOfBoundsException evt){
System.out.println(evt.getMessage());
}
return message;
}
//
static byte [] longToCharArray ( long x){
byte [] charArray = new byte [8];
for (int i = 7; i >= 0; i--){
charArray[i] = (byte) ( x & 0xFF);
x = x >>> 8;
}
return charArray;
}
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();
long []chain = { A, B, C, D};
byte []result = appendPaddingBits(message);
long []temp = new long [16];
System.out.println(result.length);
for (int k = 0; k < result.length; k += BLOCK_SIZE / BITS){
long []state = { A, B, C, D};
for (int i = 0; i < 16; i++){
temp[ i] = ((long) result[ k + i * 4 + 3] & 0xFF) |
((long) (result[ k + i * 4 + 2] & 0xFF) << 8) |
((long) (result[ k + i * 4 + 1] & 0xFF) << 16) |
((long) (result[ k + i * 4 + 0] & 0xFF) << 24);
}
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] +
(long) 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();
}
}
//Create function array
interface FunctionArrayInterface {
long runIt(long X, long Y, long Z);
}
//fM, gM, hM and iM are basic MD5 methods.
class F implements FunctionArrayInterface{
public long runIt(long X, long Y, long Z){
return (X & Y) | ( ~X & Z);
}
}
class G implements FunctionArrayInterface{
public long runIt( long X, long Y, long Z){
return (X & Z) | ( Y & ~Z);
}
}
class H implements FunctionArrayInterface{
public long runIt( long X, long Y, long Z){
return X ^ Y ^ Z;
}
}
class I implements FunctionArrayInterface{
public long runIt( long X, long Y, long Z){
return Y ^ ( X | ~Z );
}
}
计算出来结果是错的,求助。
[ 本帖最后由 洛云 于 2011-2-2 20:44 编辑 ]
搜索更多相关的解决方案:
color
----------------解决方案--------------------------------------------------------
为什么没人回答?都忙着过年?
----------------解决方案--------------------------------------------------------
百度上的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;
}
* 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;
}
----------------解决方案--------------------------------------------------------