Base64Encode函数问题,与Foxmail的编码比较。 你把Base64Encode的算法给我一份吧!谢谢了![email protected] 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 to Iamcoming我没有算法,只有函数,就是上面那个。 我这也有段代码,贴给你CString EncodeTextBase64(const CString& sText){ unsigned char cChar[255]; int nIndex1, nIndex2, nIndex3, nIndex4; int nChars; CString sBase64 = ""; char cTable[64 + 1]; CString sTemp; cTable[0] = 'A'; cTable[1] = 'B'; cTable[2] = 'C'; cTable[3] = 'D'; cTable[4] = 'E'; cTable[5] = 'F'; cTable[6] = 'G'; cTable[7] = 'H'; cTable[8] = 'I'; cTable[9] = 'J'; cTable[10] = 'K'; cTable[11] = 'L'; cTable[12] = 'M'; cTable[13] = 'N'; cTable[14] = 'O'; cTable[15] = 'P'; cTable[16] = 'Q'; cTable[17] = 'R'; cTable[18] = 'S'; cTable[19] = 'T'; cTable[20] = 'U'; cTable[21] = 'V'; cTable[22] = 'W'; cTable[23] = 'X'; cTable[24] = 'Y'; cTable[25] = 'Z'; cTable[26] = 'a'; cTable[27] = 'b'; cTable[28] = 'c'; cTable[29] = 'd'; cTable[30] = 'e'; cTable[31] = 'f'; cTable[32] = 'g'; cTable[33] = 'h'; cTable[34] = 'i'; cTable[35] = 'j'; cTable[36] = 'k'; cTable[37] = 'l'; cTable[38] = 'm'; cTable[39] = 'n'; cTable[40] = 'o'; cTable[41] = 'p'; cTable[42] = 'q'; cTable[43] = 'r'; cTable[44] = 's'; cTable[45] = 't'; cTable[46] = 'u'; cTable[47] = 'v'; cTable[48] = 'w'; cTable[49] = 'x'; cTable[50] = 'y'; cTable[51] = 'z'; cTable[52] = '0'; cTable[53] = '1'; cTable[54] = '2'; cTable[55] = '3'; cTable[56] = '4'; cTable[57] = '5'; cTable[58] = '6'; cTable[59] = '7'; cTable[60] = '8'; cTable[61] = '9'; cTable[62] = '+'; cTable[63] = '/'; cTable[64] = '='; nChars = sText.GetLength(); for (int nPos = 0; nPos < nChars; nPos++) { cChar[nPos] = sText.GetAt(nPos); } for (nPos = 0; nPos < nChars; nPos += 3) { if (nPos + 1 >= nChars) cChar[nPos + 1] = '0'; if (nPos + 2 >= nChars) cChar[nPos + 2] = '0'; nIndex4 = ( cChar[nPos + 2] & 0x3F ) & 0x3F; nIndex3 = ( ((cChar[nPos + 1] & 0x0F) << 2) | ((cChar[nPos + 2] & 0xC0) >> 6) ) & 0x3F; nIndex2 = ( ((cChar[nPos] & 3) << 4) | ((cChar[nPos + 1] & 0xF0) >> 4) ) & 0x3F; nIndex1 = ( (cChar[nPos] & 0xFC) >> 2 ) & 0x3F; if (nPos + 1 >= nChars) { nIndex3 = 64; nIndex4 = 64; } if (nPos + 2 >= nChars) { nIndex4 = 64; } sTemp.Format("%c%c%c%c", cTable[nIndex1], cTable[nIndex2], cTable[nIndex3], cTable[nIndex4]); sBase64 += sTemp; } return sBase64;} 上 去 ~楼上的代码编码和Foxmail编码的也不全一样。 Foxmail对你的编码结果是否能正确解码出来?我以前做MIME编码时也遇到过这种情况,一般只要其他的解码程序能正确解码就行,没必要强求完全一致。 可以哦,那样看来不是函数的问题了.不过我还有个问题,为什么我用这个函数编码了一些二进制文件却比foxmail的短缺了些数据呢?还有些数据不见了.我是把二进制文件分成一个个缓冲编码再拼在一齐的. 下面这个函数可以base64编码而且没错,但是就是慢得要紧,能改写成VC的吗?Public Function Base64Encode(minbyte() As Byte) As Stringmd = UBound(minbyte) + 1If md Mod 3 <> 0 Then ReDim Preserve minbyte(md + (2 - (md Mod 3)))If md Mod 3 = 1 Then minbyte(UBound(minbyte)) = 0 minbyte(UBound(minbyte) - 1) = 0ElseIf md Mod 3 = 2 Then minbyte(UBound(minbyte)) = 0End Iflinelen = 0For ml = 0 To UBound(minbyte) - 2 Step 3 DoEvents tByte = minbyte(ml) And &HFC moutbyte(0) = tByte / 4 tByte = ((minbyte(ml) And &H3) * 16) + (minbyte(ml + 1) And &HF0) / 16 moutbyte(1) = tByte tByte = ((minbyte(ml + 1) And &HF) * 4) + ((minbyte(ml + 2) And &HC0) / 64) moutbyte(2) = tByte tByte = (minbyte(ml + 2) And &H3F) moutbyte(3) = tByte basestring = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" For i = 0 To 3 moutbytee(i) = Mid(basestring, moutbyte(i) + 1, 1) Next i msendstring = msendstring & moutbytee(0) & moutbytee(1) & moutbytee(2) & moutbytee(3) linelen = linelen + 1 If linelen * 4 > 74 Then msendstring = msendstring & vbCrLf linelen = 0 End IfNextmd = md Mod 3If md = 1 Then msendstring = Left(msendstring, Len(msendstring) - 2) & "=="If md = 2 Then msendstring = Left(msendstring, Len(msendstring) - 1) & "="Base64Encode = msendstringend function .h file--------------------------#ifdef BASE64_EXPORTS#define BASE64_API __declspec(dllexport)#else#define BASE64_API __declspec(dllimport)#endif/*// This class is exported from the base64.dllclass BASE64_API CBase64 {public: CBase64(void); // TODO: add your methods here.};extern BASE64_API int nBase64;BASE64_API int fnBase64(void);//*/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 = '=';BASE64_API unsigned char *base64_encode(const unsigned char *, int, int *);BASE64_API unsigned char *base64_decode(const unsigned char *, int, int *);----------------------------.cpp file-------------------------// base64.cpp : Defines the entry point for the DLL application.#include "stdafx.h"#include "base64.h"#include <stdlib.h>BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}/**** i know,but i don't need your example ****//*// This is an example of an exported variableBASE64_API int nBase64=0;// This is an example of an exported function.//*//*BASE64_API int fnBase64(void){ return 42;}// This is the constructor of a class that has been exported.// see base64.h for the class definitionCBase64::CBase64(){ return; }*/BASE64_API unsigned char *base64_encode(unsigned char *result,const unsigned char *str, int length, int *ret_length){ const unsigned char *current = str; int i = 0; unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 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) + (current[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'; return result;}//BASE64_API unsigned char *base64_decode(const unsigned char *, int, int *);BASE64_API unsigned char *base64_decode(const unsigned char *str, int length, int *ret_length) { const unsigned char *current = str; int ch, i = 0, j = 0, k; /* this sucks for threaded environments */ static short reverse_table[256]; static int table_built; unsigned char *result; if (++table_built == 1) { char *chp; for(ch = 0; ch < 256; ch++) { chp = strchr(base64_table, ch); if(chp) { reverse_table[ch] = chp - base64_table; } else { reverse_table[ch] = -1; } } } result = (unsigned char *)malloc(length + 1); if (result == NULL) { return NULL; } /* run through the whole string, converting as we go */ while ((ch = *current++) != '\0') { if (ch == base64_pad) break; /* When Base64 gets POSTed, all pluses are interpreted as spaces. This line changes them back. It's not exactly the Base64 spec, but it is completely compatible with it (the spec says that spaces are invalid). This will also save many people considerable headache. - Turadg Aleahmad <[email protected]> */ if (ch == ' ') ch = '+'; ch = reverse_table[ch]; if (ch < 0) continue; switch(i % 4) { case 0: result[j] = ch << 2; break; case 1: result[j++] |= ch >> 4; result[j] = (ch & 0x0f) << 4; break; case 2: result[j++] |= ch >>2; result[j] = (ch & 0x03) << 6; break; case 3: result[j++] |= ch; break; } i++; } k = j; /* mop things up if we ended on a boundary */ if (ch == base64_pad) { switch(i % 4) { case 0: case 1: free(result); return NULL; case 2: k++; case 3: result[k++] = 0; } } if(ret_length) { *ret_length = j; } result[k] = '\0'; return result;} png按钮要与背景做运算呀?//下面截图把背景图片去掉就显示不对了 有关代码执行时间的疑问 VC编写USB应用程序 两个类中定义一样的函数行么?(深入浅出MFC中的疑问) 如何判断钩子是谁安装的? 如何去掉视频(电影.avi)中的字幕, 要对单文档视图进行切分窗口应该怎么做呀? VFW的资料哪有下的,或者哪个好心人有? 在win32 console程序中怎么用TRACE? 还是根本不能用TRACE? 声音输出混合的问题(100元人民币) 调查一下:请问大家有多少人是真正的程序员,又有多少人不想干程序员了?? 请问SendMessage()函数能起什么作用,一般在什么时候用,应该怎样用??
我没有算法,只有函数,就是上面那个。
{
unsigned char cChar[255];
int nIndex1, nIndex2, nIndex3, nIndex4;
int nChars;
CString sBase64 = "";
char cTable[64 + 1];
CString sTemp; cTable[0] = 'A';
cTable[1] = 'B';
cTable[2] = 'C';
cTable[3] = 'D';
cTable[4] = 'E';
cTable[5] = 'F';
cTable[6] = 'G';
cTable[7] = 'H';
cTable[8] = 'I';
cTable[9] = 'J';
cTable[10] = 'K';
cTable[11] = 'L';
cTable[12] = 'M';
cTable[13] = 'N';
cTable[14] = 'O';
cTable[15] = 'P'; cTable[16] = 'Q';
cTable[17] = 'R';
cTable[18] = 'S';
cTable[19] = 'T';
cTable[20] = 'U';
cTable[21] = 'V';
cTable[22] = 'W';
cTable[23] = 'X';
cTable[24] = 'Y';
cTable[25] = 'Z';
cTable[26] = 'a';
cTable[27] = 'b';
cTable[28] = 'c';
cTable[29] = 'd';
cTable[30] = 'e';
cTable[31] = 'f'; cTable[32] = 'g';
cTable[33] = 'h';
cTable[34] = 'i';
cTable[35] = 'j';
cTable[36] = 'k';
cTable[37] = 'l';
cTable[38] = 'm';
cTable[39] = 'n';
cTable[40] = 'o';
cTable[41] = 'p';
cTable[42] = 'q';
cTable[43] = 'r';
cTable[44] = 's';
cTable[45] = 't';
cTable[46] = 'u';
cTable[47] = 'v'; cTable[48] = 'w';
cTable[49] = 'x';
cTable[50] = 'y';
cTable[51] = 'z';
cTable[52] = '0';
cTable[53] = '1';
cTable[54] = '2';
cTable[55] = '3';
cTable[56] = '4';
cTable[57] = '5';
cTable[58] = '6';
cTable[59] = '7';
cTable[60] = '8';
cTable[61] = '9';
cTable[62] = '+';
cTable[63] = '/'; cTable[64] = '='; nChars = sText.GetLength();
for (int nPos = 0; nPos < nChars; nPos++)
{
cChar[nPos] = sText.GetAt(nPos);
} for (nPos = 0; nPos < nChars; nPos += 3)
{
if (nPos + 1 >= nChars) cChar[nPos + 1] = '0';
if (nPos + 2 >= nChars) cChar[nPos + 2] = '0';
nIndex4 = ( cChar[nPos + 2] & 0x3F ) & 0x3F;
nIndex3 = ( ((cChar[nPos + 1] & 0x0F) << 2)
| ((cChar[nPos + 2] & 0xC0) >> 6) ) & 0x3F;
nIndex2 = ( ((cChar[nPos] & 3) << 4)
| ((cChar[nPos + 1] & 0xF0) >> 4) ) & 0x3F;
nIndex1 = ( (cChar[nPos] & 0xFC) >> 2 ) & 0x3F;
if (nPos + 1 >= nChars)
{
nIndex3 = 64;
nIndex4 = 64;
}
if (nPos + 2 >= nChars)
{
nIndex4 = 64;
}
sTemp.Format("%c%c%c%c",
cTable[nIndex1],
cTable[nIndex2],
cTable[nIndex3],
cTable[nIndex4]);
sBase64 += sTemp;
} return sBase64;
}
楼上的代码编码和Foxmail编码的也不全一样。
md = UBound(minbyte) + 1If md Mod 3 <> 0 Then ReDim Preserve minbyte(md + (2 - (md Mod 3)))If md Mod 3 = 1 Then
minbyte(UBound(minbyte)) = 0
minbyte(UBound(minbyte) - 1) = 0
ElseIf md Mod 3 = 2 Then
minbyte(UBound(minbyte)) = 0
End Iflinelen = 0For ml = 0 To UBound(minbyte) - 2 Step 3
DoEvents
tByte = minbyte(ml) And &HFC
moutbyte(0) = tByte / 4
tByte = ((minbyte(ml) And &H3) * 16) + (minbyte(ml + 1) And &HF0) / 16
moutbyte(1) = tByte
tByte = ((minbyte(ml + 1) And &HF) * 4) + ((minbyte(ml + 2) And &HC0) / 64)
moutbyte(2) = tByte
tByte = (minbyte(ml + 2) And &H3F)
moutbyte(3) = tByte
basestring = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
For i = 0 To 3
moutbytee(i) = Mid(basestring, moutbyte(i) + 1, 1)
Next i
msendstring = msendstring & moutbytee(0) & moutbytee(1) & moutbytee(2) & moutbytee(3)
linelen = linelen + 1
If linelen * 4 > 74 Then
msendstring = msendstring & vbCrLf
linelen = 0
End If
Nextmd = md Mod 3
If md = 1 Then msendstring = Left(msendstring, Len(msendstring) - 2) & "=="
If md = 2 Then msendstring = Left(msendstring, Len(msendstring) - 1) & "="
Base64Encode = msendstringend function
--------------------------
#ifdef BASE64_EXPORTS
#define BASE64_API __declspec(dllexport)
#else
#define BASE64_API __declspec(dllimport)
#endif
/*
// This class is exported from the base64.dll
class BASE64_API CBase64 {
public:
CBase64(void);
// TODO: add your methods here.
};
extern BASE64_API int nBase64;
BASE64_API int fnBase64(void);
//*/
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 = '=';BASE64_API unsigned char *base64_encode(const unsigned char *, int, int *);
BASE64_API unsigned char *base64_decode(const unsigned char *, int, int *);----------------------------
.cpp file
-------------------------
// base64.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "base64.h"
#include <stdlib.h>BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}/**** i know,but i don't need your example ****/
/*
// This is an example of an exported variable
BASE64_API int nBase64=0;// This is an example of an exported function.//*/
/*BASE64_API int fnBase64(void)
{
return 42;
}
// This is the constructor of a class that has been exported.
// see base64.h for the class definition
CBase64::CBase64()
{
return;
}
*/
BASE64_API unsigned char *base64_encode(unsigned char *result,const unsigned char *str, int length, int *ret_length)
{
const unsigned char *current = str;
int i = 0;
unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 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) + (current[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';
return result;
}
//BASE64_API unsigned char *base64_decode(const unsigned char *, int, int *);
BASE64_API unsigned char *base64_decode(const unsigned char *str, int length, int *ret_length)
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
/* this sucks for threaded environments */
static short reverse_table[256];
static int table_built;
unsigned char *result; if (++table_built == 1) {
char *chp;
for(ch = 0; ch < 256; ch++) {
chp = strchr(base64_table, ch);
if(chp) {
reverse_table[ch] = chp - base64_table;
} else {
reverse_table[ch] = -1;
}
}
} result = (unsigned char *)malloc(length + 1);
if (result == NULL) {
return NULL;
} /* run through the whole string, converting as we go */
while ((ch = *current++) != '\0') {
if (ch == base64_pad) break; /* When Base64 gets POSTed, all pluses are interpreted as spaces.
This line changes them back. It's not exactly the Base64 spec,
but it is completely compatible with it (the spec says that
spaces are invalid). This will also save many people considerable
headache. - Turadg Aleahmad <[email protected]>
*/ if (ch == ' ') ch = '+'; ch = reverse_table[ch];
if (ch < 0) continue; switch(i % 4) {
case 0:
result[j] = ch << 2;
break;
case 1:
result[j++] |= ch >> 4;
result[j] = (ch & 0x0f) << 4;
break;
case 2:
result[j++] |= ch >>2;
result[j] = (ch & 0x03) << 6;
break;
case 3:
result[j++] |= ch;
break;
}
i++;
} k = j;
/* mop things up if we ended on a boundary */
if (ch == base64_pad) {
switch(i % 4) {
case 0:
case 1:
free(result);
return NULL;
case 2:
k++;
case 3:
result[k++] = 0;
}
}
if(ret_length) {
*ret_length = j;
}
result[k] = '\0';
return result;
}