热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

答网友关于base64算法的汉字编码问题

曾几何时,写了这么一文:http:blog.csdn.netprsniperarticledetails7097643网友linyanwen99经过运行发现中文下编码是错误的,这个问题是

曾几何时,写了这么一文:

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

 


推荐阅读
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
author-avatar
乃ah麟
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有