曾几何时,写了这么一文:
http://blog.csdn.net/prsniper/article/details/7097643
网友linyanwen99经过运行发现中文下编码是错误的,这个问题是客观存在的
要想用该算法计算汉字的base64编码,就要做一些改进:
主要改进几行代码就可以了,看完整的修改后的函数:
//编码,参数:要编码的字符串指针,解码后存放的位置(编码字串长度的4/3),要编码的字符串长度 ->返回结果长度 int fnBase64Encode(char *lpString, char *lpBuffer, int sLen) { register int vLen = 0; //寄存器局部变量,提速 char c = 0x00; //增加两个临时变量 char t = 0x00; while(sLen > 0) //处理整个字符串 { c = (lpString[0] >> 2 ); c = c & 0x3F; // *lpBuffer++ = BASE_CODE[(lpString[0] >> 2 ) & 0x3F]; //右移两位,与00111111是防止溢出,自加 // if(sLen > 2) //够3个字符 // { *lpBuffer++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)]; // *lpBuffer++ = BASE_CODE[((lpString[1] & 0xF) << 2) | (lpString[2] >> 6)]; // *lpBuffer++ = BASE_CODE[lpString[2] & 0x3F]; // }else *lpBuffer++ = BASE_CODE[c]; //右移两位,与00111111是防止溢出,自加 if(sLen > 2) //够3个字符 { c = (lpString[0] & 3) << 4; t = (lpString[1] >> 4) & 0x0F; /*[1]因为汉字最高位为1,右移x86填充1导致出错:所以与0x0F*/ *lpBuffer++ = BASE_CODE[(c) | (t)]; c = (lpString[1] & 0xF) << 2; t = (lpString[2] >> 6) & 0x3; /*[2]同上,汉字原因右移6位与00000011*/ *lpBuffer++ = BASE_CODE[(c) | (t)]; c = lpString[2] & 0x3F; *lpBuffer++ = BASE_CODE[c]; }else { switch(sLen) //追加“=” { case 1: *lpBuffer ++ = BASE_CODE[(lpString[0] & 3) << 4 ]; *lpBuffer ++ = '='; *lpBuffer ++ = '='; break; case 2: *lpBuffer ++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)]; *lpBuffer ++ = BASE_CODE[((lpString[1] & 0x0F) << 2) | (lpString[2] >> 6)]; *lpBuffer ++ = '='; break; } } lpString += 3; sLen -= 3; vLen +=4; } *lpBuffer = 0; return vLen; }
主要更改这个地方:
while(sLen > 0) //处理整个字符串 { c = (lpString[0] >> 2 ); c = c & 0x3F; // *lpBuffer++ = BASE_CODE[(lpString[0] >> 2 ) & 0x3F]; //右移两位,与00111111是防止溢出,自加 // if(sLen > 2) //够3个字符 // { *lpBuffer++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)]; // *lpBuffer++ = BASE_CODE[((lpString[1] & 0xF) << 2) | (lpString[2] >> 6)]; // *lpBuffer++ = BASE_CODE[lpString[2] & 0x3F]; // }else *lpBuffer++ = BASE_CODE[c]; //右移两位,与00111111是防止溢出,自加 if(sLen > 2) //够3个字符 { c = (lpString[0] & 3) << 4; t = (lpString[1] >> 4) & 0x0F; /*[1]因为汉字最高位为1,右移x86填充1导致出错:所以与0x0F*/ *lpBuffer++ = BASE_CODE[(c) | (t)]; c = (lpString[1] & 0xF) << 2; t = (lpString[2] >> 6) & 0x3; /*[2]同上,汉字原因右移6位与00000011*/ *lpBuffer++ = BASE_CODE[(c) | (t)]; c = lpString[2] & 0x3F; *lpBuffer++ = BASE_CODE[c]; }else
原因和修改前的代码,注释里已经有了.用修改后的代码可以实现你想要的汉字编码的需求.
同时,实践是检验真理的唯一标准,这是政治家说的,对于技术来说,便是检验真理,而是探究真理的深层机理
只要你了解了base64算法的原理,那么怎么完善修改和变更都不是难事了
注意:UTF8可以用这个来测试:
char sz[] = {0xE4, 0xBD, 0xA0, 0xE5, 0xA5, 0xBD, 0xEF, 0xBC, 0x8C, 0xE4, 0xB8, 0x96, 0xE7, 0x95, 0x8C, 0x00};
这是"你好,世界"的UTF-8编码,应该得到:
5L2g5aW977yM5LiW55WM