关于坑爹的编解码问题

关于坑爹的编解码问题

编解码问题从来都是搞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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 利用 SSDP 协议生成 100 Gbps DDoS 流量的真相探秘「建议收藏」

    利用 SSDP 协议生成 100 Gbps DDoS 流量的真相探秘「建议收藏」原文地址https://www.4hou.com/technology/5979.html上个月我们分享过一些反射型DDoS攻击数据,SSDP攻击的平均大小是12Gbps,我们记录的最大的反射式DDoS攻击是:1.30Mpps(每秒数百万个数据包)2.80Gbps(每秒数十亿位)3.使用940k反射器的IP几天前,我们注意到了一个不寻常的SSDP超级放大情况的发生…

    2022年10月10日
    4
  • php-面向对象

    php-面向对象

    2021年7月4日
    106
  • conda 删除源_conda删除包

    conda 删除源_conda删除包记录自己新建一个py3.5的conda环境,遇到镜像连接超级慢,清华的镜像也不太行的亚子,发现之前安装的anaconda中有一个源速度还可以。一、查看自己conda的链接进入cmdcondainfo调出conda的信息二、添加源condaconfig–addchannelshttps://repo.continuum.io/pkgs/main/condaconf…

    2022年9月27日
    4
  • RSA加密算法解读

    RSA加密算法解读图为RSA公开密钥算法的发明人,从左到右RonRivest,AdiShamir,LeonardAdleman.照片摄于1978年  RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新来的同事对它不太了解,恰好看到一本书中作者用实例对它进行了简化而生动的描述,使得高深的数学理论能够被容易地理解。我们经过整理和改写特别推荐给大家阅读,希望能够对时间…

    2022年6月1日
    40
  • 正弦、余弦和正切

    正弦、余弦和正切https://www.shuxuele.com/sine-cosine-tangent.html直角三角形正弦、余弦和正切是 三角法 里的主要函数,它们是基于一个 

    2022年8月1日
    9
  • 数据库设计工具推荐

    数据库设计工具推荐要是MySQL推荐Workbench。PD(PowerDesigner)和ERWin。大家是这样介绍的,需要的可以使用下看看。

    2022年7月4日
    35

发表回复

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

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