关于坑爹的编解码问题

关于坑爹的编解码问题

编解码问题从来都是搞IT,尤其是搞互联网的同志们的心头之痛。君不见,http请求,数据库字符,中文乱码等东西,都和字符编码有偌大的关系。

这个坑貌似是躲不过了。所以最好的方式就是:直面它,解决它。你说是不是~

首先解决一些基础概念问题。utf8 unicode ascii之间到底是什么关系?

如果这个不搞清楚,你就总是会问,我怎么把utf8转成unicode这类表述并不严谨的问题。

首先要明确一点,unicode是一种“编码”,所谓编码就是一个编号(数字)到字符的一种映射关系,就仅仅是一种一对一的映射而已,可以理解成一个很大的对应表格。unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),注意,UTF-8 是 Unicode 的实现方式之一。换一句话说,GBK、UTF-8是一种“编码格式”,是用来序列化或存储1中提到的那个“编号(数字)”的一种“格式”;GBK和UTF-8都是用来序列化或存储unicode编码的数据的,但是分别是2种不同的格式; 他们俩除了格式不一样之外,他们所关心的unicode编码范围也不一样,utf-8考虑了很多种不同国家的字符,涵盖整个unicode码表,所以其存储一个字符的编码的时候,使用的字节长度也从1字节到4字节不等;而GBK只考虑中文——在unicode中的一小部分——的字符,的编码,所以它算好了只要2个字节就能涵盖到绝大多数常用中文(2个字节能表示6w多种字符),所以它存储一个字符的时候,所用的字节长度是固定的;

所谓encode,是将逻辑上的字符,例如“a”,转化为一系列二进制串,可以用utf8,也可以用ascii等等。

所谓decode,就是将上述一系列的二进制串,转为逻辑上的字符。

两者是互逆的过程。

结合java来看一下,首先java的string使用的编码是unicode,但是,当string存在于内存中时(也就是当程序运行时、你在代码中用string类型的引用对它进行操作时、也就是string没有被存在文件中且也没有在网络中传输(序列化)时),是“只有编码而没有编码格式的”,所以java程序中的任何String对象,说它是gbk还是utf-8都是错的,gbk和utf-8是编码格式而不是编码,String在内存中不需要“编码格式”(记住编码格式是在存文件或序列化的时候使用的), 它只是一个unicode的字符串而已。

所以java里面String是不带编码格式的,而String.toByteArray(charsetName)得到的byteArray是带编码格式的(还有一种方法叫getBytes),格式就是你传入的’charsetName’,我们不妨把toByteArray的这个过程叫做“编码”,就是上面说的encode;另外,new String(byte[], charsetName)是把一个byte数组(带编码格式)以charsetName指定的编码格式翻译为一个不带编码格式的String对象,我们不妨把这个过程叫“解码”,就是上面说的decode。

具体到实际的例子,例如数据库,使用characterEncoding=utf8做连接参数,即是表示在数据库和server之间的传输的字节,都是utf8编码的。

在java中,如果你写下String str =”\u4f60\u597d”,那么本质上,是代表“你好”两个汉字。\u作为的是转义字符,所指就是unicode编码。

在转为json的过程中,例如使用gson这个三方库的时候,它会自动将其序列化为unicode的字符串。没有utf8的编码,就是\u4f60这个字符常量(as it is)

如果想要打印出某个char的unicode码,在java中可以直接转为int类型后打印,因为 The char data type is a single 16-bit Unicode character. It has a minimum value of ‘\u0000’ (or 0) and a maximum value of ‘\uffff’ (or 65,535 inclusive).

 

ref:

1] https://www.zhihu.com/question/20361462

2] http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

转载于:https://www.cnblogs.com/ShaneZhang/p/8875695.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101712.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu与centos的对比和选择「建议收藏」

    ubuntu与centos的对比和选择「建议收藏」一、分别介绍CentOS(CommunityENTerpriseOperatingSystem)是Linux发行版之一,它是来自于RedHatEnterpriseLinux依照开放源代码规定释出的源代码所编译而成。RedHatEnterpriseLinux(RHEL)是企业发行版。它每五年左右更新一次,在系统的稳定性,前瞻性和安全性上有着极大的优势。由于CentOS…

    2022年9月4日
    3
  • eclipse卸载android环境插件

    卸载eclipse-preference左侧导航栏中Android模块help-installnewsoftware–whatisalreadyinstalled?在弹出的界面选择android相关的插件卸载,重启eclipse

    2022年4月6日
    39
  • getenforce setenforce

    getenforce setenforceSELINUX转载于:https://www.cnblogs.com/todayORtomorrow/p/10507497.html

    2022年6月27日
    33
  • mongodb联表查询_mongodb聚合查询

    mongodb联表查询_mongodb聚合查询  在使用MongoDB存储数据的时候,我们查询的时候,有时候难免会需要进行连表查询。但是MongoDB本身是非关系性数据库,连表查询,很多时候,需要我们自己在代码里手工操作。但是从MongoDB3.2版本过后,我们可以使用lookup∗∗∗进行连表查询。下面就简单介绍一下MongoDB的∗∗∗lookup∗∗∗进行连表查询。下面就简单介绍一下MongoDB的∗∗∗lookup***进行…

    2022年9月14日
    0
  • 大富豪3辅助器_加油站大亨作弊

    大富豪3辅助器_加油站大亨作弊   开心001最近新增加了一个功能:超级大亨,开始那几天没有外挂能进行操作,自己也很感兴趣,就动了编写一个外挂练习的念头。网上最早的一篇讲解开心网外挂的是http://www.turbozv.com/read.php/838.htm,写得很详细。   首先要分析下超级大亨的游戏赚钱手段:   1.每4小时登录本组件1次,将获得一定的资金奖励;   2.物品的市场价格会不断浮

    2022年9月3日
    2
  • pycharm中彻底删除一个工程的步骤_ios已购项目永久删除

    pycharm中彻底删除一个工程的步骤_ios已购项目永久删除第一步    File——>CloseProject找到要关闭的项目,点击×。第二步    找到该项目保存的路径,shift+del永久删除。

    2022年8月28日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号