用现在网上可以找到的一般MD5算法处理过后,
无法在Unicode环境下得到正常的输入出结。Unicode编程经验欠缺,自己处理太费力。
哪位可以给个Unicode下可用的MD5算法?不胜感激!

解决方案 »

  1.   


    md5.h  
    #ifndef _MD5_H
    #define _MD5_H#ifndef uint8
    #define uint8  unsigned char
    #endif#ifndef uint32
    #define uint32 unsigned long int
    #endiftypedef struct
    {
        uint32 total[2];
        uint32 state[4];
        uint8 buffer[64];
    }
    md5_context;void md5_starts( md5_context *ctx );
    void md5_update( md5_context *ctx, uint8 *input, uint32 length );
    void md5_finish( md5_context *ctx, uint8 digest[16] );#endif /* md5.h */ 
    md5.c  
    /*
     *  RFC 1321 compliant MD5 implementation
     *
     *  Copyright (C) 2001-2003  Christophe Devine
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 2 of the License, or
     *  (at your option) any later version.
     *
     *  This program is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *  GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program; if not, write to the Free Software
     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     */#include <string.h>#include "md5.h"#define GET_UINT32(n,b,i)                       \
    {                                               \
        (n) = ( (uint32) (b)[(i)    ]       )       \
            | ( (uint32) (b)[(i) + 1] <<  8 )       \
            | ( (uint32) (b)[(i) + 2] << 16 )       \
            | ( (uint32) (b)[(i) + 3] << 24 );      \
    }#define PUT_UINT32(n,b,i)                       \
    {                                               \
        (b)[(i)    ] = (uint8) ( (n)       );       \
        (b)[(i) + 1] = (uint8) ( (n) >>  8 );       \
        (b)[(i) + 2] = (uint8) ( (n) >> 16 );       \
        (b)[(i) + 3] = (uint8) ( (n) >> 24 );       \
    }void md5_starts( md5_context *ctx )
    {
        ctx->total[0] = 0;
        ctx->total[1] = 0;    ctx->state[0] = 0x67452301;
        ctx->state[1] = 0xEFCDAB89;
        ctx->state[2] = 0x98BADCFE;
        ctx->state[3] = 0x10325476;
    }void md5_process( md5_context *ctx, uint8 data[64] )
    {
        uint32 X[16], A, B, C, D;    GET_UINT32( X[0],  data,  0 );
        GET_UINT32( X[1],  data,  4 );
        GET_UINT32( X[2],  data,  8 );
        GET_UINT32( X[3],  data, 12 );
        GET_UINT32( X[4],  data, 16 );
        GET_UINT32( X[5],  data, 20 );
        GET_UINT32( X[6],  data, 24 );
        GET_UINT32( X[7],  data, 28 );
        GET_UINT32( X[8],  data, 32 );
        GET_UINT32( X[9],  data, 36 );
        GET_UINT32( X[10], data, 40 );
        GET_UINT32( X[11], data, 44 );
        GET_UINT32( X[12], data, 48 );
        GET_UINT32( X[13], data, 52 );
        GET_UINT32( X[14], data, 56 );
        GET_UINT32( X[15], data, 60 );#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))#define P(a,b,c,d,k,s,t)                                \
    {                                                       \
        a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
    }    A = ctx->state[0];
        B = ctx->state[1];
        C = ctx->state[2];
        D = ctx->state[3];#define F(x,y,z) (z ^ (x & (y ^ z)))    P( A, B, C, D,  0,  7, 0xD76AA478 );
        P( D, A, B, C,  1, 12, 0xE8C7B756 );
        P( C, D, A, B,  2, 17, 0x242070DB );
        P( B, C, D, A,  3, 22, 0xC1BDCEEE );
        P( A, B, C, D,  4,  7, 0xF57C0FAF );
        P( D, A, B, C,  5, 12, 0x4787C62A );
        P( C, D, A, B,  6, 17, 0xA8304613 );
        P( B, C, D, A,  7, 22, 0xFD469501 );
        P( A, B, C, D,  8,  7, 0x698098D8 );
        P( D, A, B, C,  9, 12, 0x8B44F7AF );
        P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
        P( B, C, D, A, 11, 22, 0x895CD7BE );
        P( A, B, C, D, 12,  7, 0x6B901122 );
        P( D, A, B, C, 13, 12, 0xFD987193 );
        P( C, D, A, B, 14, 17, 0xA679438E );
        P( B, C, D, A, 15, 22, 0x49B40821 );#undef F#define F(x,y,z) (y ^ (z & (x ^ y)))    P( A, B, C, D,  1,  5, 0xF61E2562 );
        P( D, A, B, C,  6,  9, 0xC040B340 );
        P( C, D, A, B, 11, 14, 0x265E5A51 );
        P( B, C, D, A,  0, 20, 0xE9B6C7AA );
        P( A, B, C, D,  5,  5, 0xD62F105D );
        P( D, A, B, C, 10,  9, 0x02441453 );
        P( C, D, A, B, 15, 14, 0xD8A1E681 );
        P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
        P( A, B, C, D,  9,  5, 0x21E1CDE6 );
        P( D, A, B, C, 14,  9, 0xC33707D6 );
        P( C, D, A, B,  3, 14, 0xF4D50D87 );
        P( B, C, D, A,  8, 20, 0x455A14ED );
        P( A, B, C, D, 13,  5, 0xA9E3E905 );
        P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
        P( C, D, A, B,  7, 14, 0x676F02D9 );
        P( B, C, D, A, 12, 20, 0x8D2A4C8A );#undef F
        
    #define F(x,y,z) (x ^ y ^ z)    P( A, B, C, D,  5,  4, 0xFFFA3942 );
        P( D, A, B, C,  8, 11, 0x8771F681 );
        P( C, D, A, B, 11, 16, 0x6D9D6122 );
        P( B, C, D, A, 14, 23, 0xFDE5380C );
        P( A, B, C, D,  1,  4, 0xA4BEEA44 );
        P( D, A, B, C,  4, 11, 0x4BDECFA9 );
        P( C, D, A, B,  7, 16, 0xF6BB4B60 );
        P( B, C, D, A, 10, 23, 0xBEBFBC70 );
        P( A, B, C, D, 13,  4, 0x289B7EC6 );
        P( D, A, B, C,  0, 11, 0xEAA127FA );
        P( C, D, A, B,  3, 16, 0xD4EF3085 );
        P( B, C, D, A,  6, 23, 0x04881D05 );
        P( A, B, C, D,  9,  4, 0xD9D4D039 );
        P( D, A, B, C, 12, 11, 0xE6DB99E5 );
        P( C, D, A, B, 15, 16, 0x1FA27CF8 );
        P( B, C, D, A,  2, 23, 0xC4AC5665 );#undef F#define F(x,y,z) (y ^ (x | ~z))    P( A, B, C, D,  0,  6, 0xF4292244 );
        P( D, A, B, C,  7, 10, 0x432AFF97 );
        P( C, D, A, B, 14, 15, 0xAB9423A7 );
        P( B, C, D, A,  5, 21, 0xFC93A039 );
        P( A, B, C, D, 12,  6, 0x655B59C3 );
        P( D, A, B, C,  3, 10, 0x8F0CCC92 );
        P( C, D, A, B, 10, 15, 0xFFEFF47D );
        P( B, C, D, A,  1, 21, 0x85845DD1 );
        P( A, B, C, D,  8,  6, 0x6FA87E4F );
        P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
        P( C, D, A, B,  6, 15, 0xA3014314 );
        P( B, C, D, A, 13, 21, 0x4E0811A1 );
        P( A, B, C, D,  4,  6, 0xF7537E82 );
        P( D, A, B, C, 11, 10, 0xBD3AF235 );
        P( C, D, A, B,  2, 15, 0x2AD7D2BB );
        P( B, C, D, A,  9, 21, 0xEB86D391 );#undef F    ctx->state[0] += A;
        ctx->state[1] += B;
        ctx->state[2] += C;
        ctx->state[3] += D;
    }
      

  2.   

    void md5_update( md5_context *ctx, uint8 *input, uint32 length )
    {
        uint32 left, fill;    if( ! length ) return;    left = ctx->total[0] & 0x3F;
        fill = 64 - left;    ctx->total[0] += length;
        ctx->total[0] &= 0xFFFFFFFF;    if( ctx->total[0] < length )
            ctx->total[1]++;    if( left && length >= fill )
        {
            memcpy( (void *) (ctx->buffer + left),
                    (void *) input, fill );
            md5_process( ctx, ctx->buffer );
            length -= fill;
            input  += fill;
            left = 0;
        }    while( length >= 64 )
        {
            md5_process( ctx, input );
            length -= 64;
            input  += 64;
        }    if( length )
        {
            memcpy( (void *) (ctx->buffer + left),
                    (void *) input, length );
        }
    }static uint8 md5_padding[64] =
    {
     0x80, 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
    };void md5_finish( md5_context *ctx, uint8 digest[16] )
    {
        uint32 last, padn;
        uint32 high, low;
        uint8 msglen[8];    high = ( ctx->total[0] >> 29 )
             | ( ctx->total[1] <<  3 );
        low  = ( ctx->total[0] <<  3 );    PUT_UINT32( low,  msglen, 0 );
        PUT_UINT32( high, msglen, 4 );    last = ctx->total[0] & 0x3F;
        padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );    md5_update( ctx, md5_padding, padn );
        md5_update( ctx, msglen, 8 );    PUT_UINT32( ctx->state[0], digest,  0 );
        PUT_UINT32( ctx->state[1], digest,  4 );
        PUT_UINT32( ctx->state[2], digest,  8 );
        PUT_UINT32( ctx->state[3], digest, 12 );
    }#ifdef TEST#include <stdlib.h>
    #include <stdio.h>/*
     * those are the standard RFC 1321 test vectors
     */static char *msg[] = 
    {
        "",
        "a",
        "abc",
        "message digest",
        "abcdefghijklmnopqrstuvwxyz",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        "12345678901234567890123456789012345678901234567890123456789012" \
            "345678901234567890"
    };static char *val[] =
    {
        "d41d8cd98f00b204e9800998ecf8427e",
        "0cc175b9c0f1b6a831c399e269772661",
        "900150983cd24fb0d6963f7d28e17f72",
        "f96b697d7cb7938d525a2f31aaf161d0",
        "c3fcd3d76192e4007dfb496cca67e13b",
        "d174ab98d277d9f5a5611c2c9f419d9f",
        "57edf4a22be3c955ac49da2e2107b67a"
    };int main( int argc, char *argv[] )
    {
        FILE *f;
        int i, j;
        char output[33];
        md5_context ctx;
        unsigned char buf[1000];
        unsigned char md5sum[16];    if( argc < 2 )
        {
            printf( "\n MD5 Validation Tests:\n\n" );        for( i = 0; i < 7; i++ )
            {
                printf( " Test %d ", i + 1 );            md5_starts( &ctx );
                md5_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) );
                md5_finish( &ctx, md5sum );            for( j = 0; j < 16; j++ )
                {
                    sprintf( output + j * 2, "%02x", md5sum[j] );
                }            if( memcmp( output, val[i], 32 ) )
                {
                    printf( "failed!\n" );
                    return( 1 );
                }            printf( "passed.\n" );
            }        printf( "\n" );
        }
        else
        {
            if( ! ( f = fopen( argv[1], "rb" ) ) )
            {
                perror( "fopen" );
                return( 1 );
            }        md5_starts( &ctx );        while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
            {
                md5_update( &ctx, buf, i );
            }        md5_finish( &ctx, md5sum );        for( j = 0; j < 16; j++ )
            {
                printf( "%02x", md5sum[j] );
            }        printf( "  %s\n", argv[1] );
        }    return( 0 );
    }#endif 
      

  3.   

    如下处理后,单个字符的可以在Unicode下可以输出正确值。
    如,a 0 ; z等,和在ANIS模式下的结果一样。
    位多个字符的结果就不一样了。// MD5Checksum.h: interface for the MD5Checksum class.#if !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)
    #define AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    class CMD5Checksum  
    {
    public:
    //interface functions for the RSA MD5 calculation
    static CString GetMD5(BYTE* pBuf, UINT nLength);
    static CString GetMD5(CFile& File);
    static CString GetMD5(const CString& strFilePath);protected:
    //constructor/destructor
    CMD5Checksum();
    virtual ~CMD5Checksum() {}; //RSA MD5 implementation
    void Transform(BYTE Block[64]);
    void Update(BYTE* Input, ULONG nInputLen);
    CString Final();
    inline DWORD RotateLeft(DWORD x, int n);
    inline void FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
    inline void GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
    inline void HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
    inline void II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T); //utility functions
    void DWordToByte(BYTE* Output, DWORD* Input, UINT nLength);
    void ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength);private:
    BYTE  m_lpszBuffer[64]; //input buffer
    ULONG m_nCount[2]; //number of bits, modulo 2^64 (lsb first)
    ULONG m_lMD5[4]; //MD5 checksum
    };#endif // !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)
      

  4.   

    // MD5Checksum.cpp: implementation of the MD5Checksum class.
    //
    #include "stdafx.h"
    #include "MD5Checksum.h"
    #include "MD5ChecksumDefines.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif
    CString CMD5Checksum::GetMD5(BYTE* pBuf, UINT nLength)
    {
    //entry invariants
    AfxIsValidAddress(pBuf,nLength,FALSE); //calculate and return the checksum
    CMD5Checksum MD5Checksum;
    MD5Checksum.Update( pBuf, nLength );
    return MD5Checksum.Final();
    }
    DWORD CMD5Checksum::RotateLeft(DWORD x, int n)
    {
    //check that DWORD is 4 bytes long - true in Visual C++ 6 and 32 bit Windows
    ASSERT( sizeof(x) == 4 ); //rotate and return x
    return (x << n) | (x >> (32-n));
    }void CMD5Checksum::FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
    {
    DWORD F = (B & C) | (~B & D);
    A += F + X + T;
    A = RotateLeft(A, S);
    A += B;
    }
    void CMD5Checksum::GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
    {
    DWORD G = (B & D) | (C & ~D);
    A += G + X + T;
    A = RotateLeft(A, S);
    A += B;
    }void CMD5Checksum::HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
    {
    DWORD H = (B ^ C ^ D);
    A += H + X + T;
    A = RotateLeft(A, S);
    A += B;
    }void CMD5Checksum::II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
    {
    DWORD I = (C ^ (B | ~D));
    A += I + X + T;
    A = RotateLeft(A, S);
    A += B;
    }void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength)
    {
    //entry invariants
    ASSERT( nLength % 4 == 0 );
    ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) );
    ASSERT( AfxIsValidAddress(Input, nLength, FALSE) ); //initialisations
    UINT i=0; //index to Output array
    UINT j=0; //index to Input array //transfer the data by shifting and copying
    for ( ; j < nLength; i++, j += 4)
    {
    Output[i] = (ULONG)Input[j] | 
    (ULONG)Input[j+1] << 8 | 
    (ULONG)Input[j+2] << 16 | 
    (ULONG)Input[j+3] << 24;
    }
    }
      

  5.   

    void CMD5Checksum::Transform(BYTE Block[64])
    {
    //initialise local data with current checksum
    ULONG a = m_lMD5[0];
    ULONG b = m_lMD5[1];
    ULONG c = m_lMD5[2];
    ULONG d = m_lMD5[3]; //copy BYTES from input 'Block' to an array of ULONGS 'X'
    ULONG X[16];
    ByteToDWord( X, Block, 64 ); //Perform Round 1 of the transformation
    FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01); 
    FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02); 
    FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03); 
    FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04); 
    FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05); 
    FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06); 
    FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07); 
    FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08); 
    FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09); 
    FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10); 
    FF (c, d, a, b, X[10], MD5_S13, MD5_T11); 
    FF (b, c, d, a, X[11], MD5_S14, MD5_T12); 
    FF (a, b, c, d, X[12], MD5_S11, MD5_T13); 
    FF (d, a, b, c, X[13], MD5_S12, MD5_T14); 
    FF (c, d, a, b, X[14], MD5_S13, MD5_T15); 
    FF (b, c, d, a, X[15], MD5_S14, MD5_T16);  //Perform Round 2 of the transformation
    GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17); 
    GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18); 
    GG (c, d, a, b, X[11], MD5_S23, MD5_T19); 
    GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20); 
    GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21); 
    GG (d, a, b, c, X[10], MD5_S22, MD5_T22); 
    GG (c, d, a, b, X[15], MD5_S23, MD5_T23); 
    GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24); 
    GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25); 
    GG (d, a, b, c, X[14], MD5_S22, MD5_T26); 
    GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27); 
    GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28); 
    GG (a, b, c, d, X[13], MD5_S21, MD5_T29); 
    GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30); 
    GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31); 
    GG (b, c, d, a, X[12], MD5_S24, MD5_T32);  //Perform Round 3 of the transformation
    HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); 
    HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34); 
    HH (c, d, a, b, X[11], MD5_S33, MD5_T35); 
    HH (b, c, d, a, X[14], MD5_S34, MD5_T36); 
    HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37); 
    HH (d, a, b, c, X[ 4], MD5_S32, MD5_T38); 
    HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39); 
    HH (b, c, d, a, X[10], MD5_S34, MD5_T40); 
    HH (a, b, c, d, X[13], MD5_S31, MD5_T41); 
    HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42); 
    HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43); 
    HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44); 
    HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45); 
    HH (d, a, b, c, X[12], MD5_S32, MD5_T46); 
    HH (c, d, a, b, X[15], MD5_S33, MD5_T47); 
    HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48);  //Perform Round 4 of the transformation
    II (a, b, c, d, X[ 0], MD5_S41, MD5_T49); 
    II (d, a, b, c, X[ 7], MD5_S42, MD5_T50); 
    II (c, d, a, b, X[14], MD5_S43, MD5_T51); 
    II (b, c, d, a, X[ 5], MD5_S44, MD5_T52); 
    II (a, b, c, d, X[12], MD5_S41, MD5_T53); 
    II (d, a, b, c, X[ 3], MD5_S42, MD5_T54); 
    II (c, d, a, b, X[10], MD5_S43, MD5_T55); 
    II (b, c, d, a, X[ 1], MD5_S44, MD5_T56); 
    II (a, b, c, d, X[ 8], MD5_S41, MD5_T57); 
    II (d, a, b, c, X[15], MD5_S42, MD5_T58); 
    II (c, d, a, b, X[ 6], MD5_S43, MD5_T59); 
    II (b, c, d, a, X[13], MD5_S44, MD5_T60); 
    II (a, b, c, d, X[ 4], MD5_S41, MD5_T61); 
    II (d, a, b, c, X[11], MD5_S42, MD5_T62); 
    II (c, d, a, b, X[ 2], MD5_S43, MD5_T63); 
    II (b, c, d, a, X[ 9], MD5_S44, MD5_T64);  //add the transformed values to the current checksum
    m_lMD5[0] += a;
    m_lMD5[1] += b;
    m_lMD5[2] += c;
    m_lMD5[3] += d;
    }
      

  6.   

    又不能连续回复三次以上,又不能写太长,有点烦
    (续)
    CMD5Checksum::CMD5Checksum()
    {
    // zero members
    memset( m_lpszBuffer, 0, 64 );
    m_nCount[0] = m_nCount[1] = 0; // Load magic state initialization constants
    m_lMD5[0] = MD5_INIT_STATE_0;
    m_lMD5[1] = MD5_INIT_STATE_1;
    m_lMD5[2] = MD5_INIT_STATE_2;
    m_lMD5[3] = MD5_INIT_STATE_3;
    }
    void CMD5Checksum::DWordToByte(BYTE* Output, DWORD* Input, UINT nLength )
    {
    //entry invariants
    ASSERT( nLength % 4 == 0 );
    ASSERT( AfxIsValidAddress(Output, nLength, TRUE) );
    ASSERT( AfxIsValidAddress(Input, nLength/4, FALSE) ); //transfer the data by shifting and copying
    UINT i = 0;
    UINT j = 0;
    for ( ; j < nLength; i++, j += 4) 
    {
    Output[j] =   (UCHAR)(Input[i] & 0xff);
    Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff);
    Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff);
    Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff);
    }
    }
    CString CMD5Checksum::Final()
    {
    //Save number of bits
    BYTE Bits[8];
    DWordToByte( Bits, m_nCount, 8 ); //Pad out to 56 mod 64.
    UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3f);
    UINT nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);
    Update( PADDING, nPadLen ); //Append length (before padding)
    Update( Bits, 8 ); //Store final state in 'lpszMD5'
    const int nMD5Size = 16;
    unsigned char lpszMD5[ nMD5Size ];
    DWordToByte( lpszMD5, m_lMD5, nMD5Size ); //Convert the hexadecimal checksum to a CString
    CString strMD5;
    for ( int i=0; i < nMD5Size; i++) 
    {
    CString Str;
    if (lpszMD5[i] == 0) {
    Str = CString("00");
    }
    else if (lpszMD5[i] <= 15)  {
    Str.Format(_T("0%X"),lpszMD5[i]); //for Unicode Build
    }
    else {
    Str.Format(_T("%x"),lpszMD5[i]); //for Unicode Build
    } ASSERT( Str.GetLength() == 2 );

    strMD5 += Str; }
    ASSERT( strMD5.GetLength() == 32 );
    return strMD5;
    }void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen )
    {
    //Compute number of bytes mod 64
    UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F); //Update number of bits
    if ( ( m_nCount[0] += nInputLen << 3 )  <  ( nInputLen << 3) )
    {
    m_nCount[1]++;
    }
    m_nCount[1] += (nInputLen >> 29); //Transform as many times as possible.
    UINT i=0;
    UINT nPartLen = 64 - nIndex;
    if (nInputLen >= nPartLen) 
    {
    memcpy( &m_lpszBuffer[nIndex], Input, nPartLen );
    Transform( m_lpszBuffer );
    for (i = nPartLen; i + 63 < nInputLen; i += 64) 
    {
    Transform( &Input[i] );
    }
    nIndex = 0;

    else 
    {
    i = 0;
    } // Buffer remaining input
    memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i);
    }
    在Unicode下调用 CMD5Checksum::GetMD5(BYTE* pBuf, UINT nLength); 
    输入a的结果为 0cc175b9c0f1b6a831c399e269772661, 和ANSI下得到的一样, 正确。但aa的输出结果为 4144e19546de78a3623da7364d04f11
    而正确值该是 4124bc0a9335c27f086f24ba207a4912。
      

  7.   

    好像没表达清楚,自己了事儿了。
    还是谢谢goodboyws。我原来的意思是不管是ANSI或者UNICODE,输入相同参数量获得相同的MD5值。
    不过如果String中包括ANSI >128的话好像难办的样子。
    用相同的代码,同时考虑ANSI和Unicode好像不太可能。我对ANSI<128是,转换为Byte时进行了WideCharToMultiByte转换了,这样Unicode下的代码稍稍改一下,就可以获得原来ANSI的代码相同的结果了。
    反正我是用来处理密码的加密...不过话又说回来,现在CSDN人怎么这么少啊?