unsigned char *base64_encode(const char *str,int length,int *ret_length) 

static char base64_table[] = 
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 
'M', 
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 
'Z', 
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 
'm', 
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 
'z', 
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', 
'\0' 
}; 
static char base64_pad = '='; 
//const char *current = str;
unsigned const char *current = (unsigned const char*)str;  
int i = 0; 
unsigned char *result = (unsigned char *)malloc(((length + 3 - lengt 
h % 3) * 4 / 3 + 1) * sizeof(char)); 
while (length > 2) { /* keep going until we have less than 24 bits * 


result[i++] = base64_table[current[0] >> 2]; 
result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1 
] >> 4)]; 
result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2 
] >> 6)]; 
result[i++] = base64_table[current[2] & 0x3f]; 
current += 3; 
length -= 3; /* we just handle 3 octets of data */ 

/* now deal with the tail end of things */ 
if (length != 0) { 
result[i++] = base64_table[current[0] >> 2]; 
if (length > 1) { 
result[i++] = base64_table[((current[0] & 0x03 ) << 4) + (curren 
t[1] >> 4)]; 
result[i++] = base64_table[(current[1] & 0x0f) << 2]; 
result[i++] = base64_pad; 

else { 
result[i++] = base64_table[(current[0] & 0x03) << 4]; 
result[i++] = base64_pad; 
result[i++] = base64_pad; 


if(ret_length) { 
*ret_length = i; 

result[i] = '\0'; // printf("%s\n",result); 
return result; 

解决方案 »

  1.   

    //将BASE64的字符转换成编号,详细见RFC1521
    //参数:BASE64Char为要转换的字符
    //返回值为响应的编号,-1为出错,-2为PAD
    CHAR CPop3Client::BASE64Char2Num(CHAR BASE64Char)
    {
    if (BASE64Char >= 'A' && BASE64Char <= 'Z')
    {
    return BASE64Char - 'A';
    }
    if (BASE64Char >= 'a' && BASE64Char <= 'z')
    {
    return BASE64Char - 'a' + 26;
    }
    if (BASE64Char >= '0' && BASE64Char <= '9')
    {
    return BASE64Char - '0' + 52;
    }
    if ('+' == BASE64Char)
    {
    return 62;
    }
    if ('/' == BASE64Char)
    {
    return 63;
    }
    if ('=' == BASE64Char)
    {
    return -2;
    }
    return -1;
    }
      

  2.   

    接上面//成功时,vc需要SysFreeString释放返回的内存
    //将BASE64的加密字符串,解密成ASCII字符串
    STDMETHODIMP CPop3Client::DecodeBASE64(BSTR SourceString, BSTR *pVal)
    {
    // TODO: Add your implementation code here
    if (pVal == NULL)
    return E_POINTER;
    USES_CONVERSION;
    LPSTR string = W2A(SourceString);//原始字符串
    int nStrLen = lstrlen(string);//字符串长度
    LPSTR strRet = new CHAR[nStrLen + 1];//存储返回值
    BYTE chPos = 0;//当前要插入的BIT位,相对与字符
    ULONG posBASE64Str = 0;
    ULONG posRetStr = 0;//当前要写入的返回字符串的指针
    BOOL bInsertBack = FALSE;//当要跨字符边界时FALSE为插入以BIT为边界的前半部分,
                      //TRUE为插入以BIT为边界的后半部分,

    memset(strRet, 0, nStrLen + 1);
    CHAR ch;
    while('\0' != string[posBASE64Str])
    {
    ch = BASE64Char2Num(string[posBASE64Str]);
    if (-1 == ch)
    {
    char buf[256];
    LoadString(_Module.m_hInstResource, IDS_ERRBASE64STRING, buf, sizeof buf);
    return Error(buf);
    }
    if (-2 == ch)
    {
    posRetStr++;
    posBASE64Str++;
    chPos = 0;
    continue;
    }
    if (0 == chPos)
    {
    strRet[posRetStr] |= ((UCHAR)ch << 2) & 0xfc;// Bin:11111100
    chPos = 6;
    posBASE64Str++;
    bInsertBack = TRUE;
    }
    else if (6 == chPos)
    {
    if (TRUE == bInsertBack)
    {
    strRet[posRetStr] |= ((UCHAR)ch >> 4) & 0x03;//Bin:00000011
    posRetStr++;
    bInsertBack = FALSE;
    }
    else
    {
    strRet[posRetStr] |= ((UCHAR)ch << 4) & 0xf0;//Bin:11110000
    posBASE64Str++;
    chPos = 4;
    bInsertBack = TRUE;
    }
    }
    else if (4 == chPos)
    {
    if (TRUE == bInsertBack)
    {
    strRet[posRetStr] |= ((UCHAR)ch >> 2) & 0x0f;//Bin:00001111
    posRetStr ++;
    bInsertBack = FALSE;
    }
    else
    {
    strRet[posRetStr] |= ((UCHAR)ch << 6) & 0xc0;//Bin:11000000
    posBASE64Str++;
    chPos = 2;
    }
    }
    else if (2 == chPos)
    {
    strRet[posRetStr] |= ((UCHAR)ch) & 0x3f;//Bin:00111111
    chPos = 0;
    posRetStr ++;
    posBASE64Str++;
    }
    }
    *pVal = SysAllocString(A2W(strRet));
    return S_OK;
    }
      

  3.   

    来自我的主页:mentals.yes8.com
    此代码是一个 BCB 的单元,非常简单,提供了四个函数, 要改成 Delphi 或其它 C/C++ 也很容易,有需要的自已改吧。此代码经过测试,结果正确。     下面是头文件: //---------------------------------------------------------------------------
    //  MIME & BASE64 Encode/Decode unit. (H)
    //  Copyright (c) 2000 Mental Studio - http://mentals.126.com
    //  Author : Raptor - [email protected]
    //---------------------------------------------------------------------------
    #ifndef mimeb64H
    #define mimeb64H
    //---------------------------------------------------------------------------AnsiString MimeEncode( AnsiString s );
    AnsiString MimeDecode( AnsiString s );
    AnsiString Base64Encode( AnsiString s );
    AnsiString Base64Decode( AnsiString s );
    //---------------------------------------------------------------------------
    #endif
            下面是 CPP 文件: //---------------------------------------------------------------------------
    //  MIME & BASE64 Encode/Decode unit. (CPP)
    //  Copyright (c) 2000 Mental Studio - http://mentals.126.com
    //  Author : Raptor - [email protected]
    //---------------------------------------------------------------------------#include 
    #pragma hdrstop#include "mimeb64.h"//---------------------------------------------------------------------------
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    //  4bit binary to char 0-F
    char Hex2Chr( Byte n )
    {
        n &= 0xF;
        if ( n < 10 )
            return ( char )( n + '0' );
        else
            return ( char )( n - 10 + 'A' );
    }
    //---------------------------------------------------------------------------
    //  char 0-F to 4bit binary
    Byte Chr2Hex( char c )
    {
        c = toupper( c );
        if ( c >= '0' && c <= '9' )
            return ( int )( c - '0' );
        else if ( c >= 'A' && c <= 'F' )
            return ( int )( c - 'A' + 10 );
        else
            return -1;
    }
    //---------------------------------------------------------------------------
    //  Base64 code table
    //  0-63 : A-Z(25) a-z(51), 0-9(61), +(62), /(63)
    char __fastcall Base2Chr( Byte n )
    {
        n &= 0x3F;
        if ( n < 26 )
            return ( char )( n + 'A' );
        else if ( n < 52 )
            return ( char )( n - 26 + 'a' );
        else if ( n < 62 )
            return ( char )( n - 52 + '0' );
        else if ( n == 62 )
            return '+';
        else
            return '/';
    }
    //---------------------------------------------------------------------------
    Byte Chr2Base( char c )
    {
        if ( c >= 'A' && c <= 'Z' )
            return ( Byte )( c - 'A' );
        else if ( c >= 'a' && c <= 'z' )
            return ( Byte )( c - 'a' + 26 );
        else if ( c >= '0' && c <= '9' )
            return ( Byte )( c - '0' + 52 );
        else if ( c == '+' )
            return 62;
        else
            return 63;
    }
    //---------------------------------------------------------------------------
    //
    AnsiString MimeEncode( AnsiString s )
    {
        AnsiString asTemp = "";
        int i = 1, n = s.Length( );    while ( i <= n )
        {
            asTemp += '=';
            asTemp += Hex2Chr( ( Byte )( s[i] >> 4 ) );
            asTemp += Hex2Chr( ( Byte )( s[i] ) );
            i++;
        }
        return asTemp;
    }
    //---------------------------------------------------------------------------
    //
    AnsiString MimeDecode( AnsiString s )
    {
        AnsiString asTemp = "";
        int i = 1, n = s.Length( );
        Byte ch, cl;    //  因为有些软件(e.g.Foxmail)对一些 < 0x7f 的字符不编码,此函数作了一些修改    while ( i <= n )
        {
            if ( ( s[i] == '=' ) && ( i + 2 <= n ) )
            {
                ch = Chr2Hex( s[i + 1] );
                cl = Chr2Hex( s[i + 2] );
                if ( ( ch == ( Byte )-1 ) || ( cl == ( Byte )-1 ) )
                    asTemp += s[i]; // 未编码的'='
                else
                {
                    asTemp += ( char )( ( ch << 4 ) | cl );
                    i += 2;
                }
            }
            else
                asTemp += s[i]; // 未编码的字符
            i++;
        }
        return asTemp;
    }
    //---------------------------------------------------------------------------
    //
    AnsiString Base64Encode( AnsiString s )
    {
        int n = s.Length( );
        Byte c, t;
        AnsiString asTemp = "";    for ( int i = 1; i <= n; i++ )
        {
            c = s[i];
            if ( i % 3 == 1 )
            {
                asTemp += Base2Chr( c >> 2 );
                t = ( c << 4 ) & 0x3F;
            }
            else if ( i % 3 == 2 )
            {
                asTemp += Base2Chr( t | ( c >> 4 ) );
                t = ( c << 2 ) & 0x3F;
            }
            else
            {
                asTemp += Base2Chr( t | ( c >> 6 ) );
                asTemp += Base2Chr( c );
            }
        }
        if ( n % 3 != 0 )
        {
            asTemp += Base2Chr( t );
            if ( n % 3 == 1 )
                asTemp += "==";
            else
                asTemp += "=";
        }
        return asTemp;
    }
    //---------------------------------------------------------------------------
    //
    AnsiString Base64Decode( AnsiString s )
    {
        int n = s.Length( );
        Byte c, t;
        AnsiString asTemp = "";    for ( int i = 1; i <= n; i++ )
        {
            if ( s[i] == '=' )
                break;
            c = Chr2Base( s[i] );
            if ( i % 4 == 1 )
                t = c << 2;
            else if ( i % 4 == 2 )
            {
                asTemp += ( char )( t | ( c >> 4 ) );
                t = ( Byte )( c << 4 );
            }
            else if ( i % 4 == 3 )
            {
                asTemp += ( char )( t | ( c >> 2 ) );
                t = ( Byte )( c << 6 );
            }
            else
                asTemp += ( char )( t | c );
        }
        return asTemp;
    }
    //---------------------------------------------------------------------------
      

  4.   

    delphi的例子 Demos\FastNet\Uue (UUencode 和 MIME/base64 的编解码)