关于坑爹的编解码问题

关于坑爹的编解码问题

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


相关推荐

  • 【SVN】SVN服务器搭建,客户端使用,在VS Code 中使用SVN

    【SVN】SVN服务器搭建,客户端使用,在VS Code 中使用SVN1.软件下载http://subversion.apache.org/packages.html#windows①VisualSVN服务端②TortoiseSVN客户端③Chinese,simplified语言包④vscode下载2.在vscode使用svn①在vscode里面下载TortoiseSVNforVSCode插件②配置svn环境变量和在……

    2022年7月19日
  • 阿里云分析数据库_阿里云用的什么数据库

    阿里云分析数据库_阿里云用的什么数据库前言由于工作中应用到了阿里的分析型数据库产品,虽然它类似于mysql,但又有一些区别,通过好好的了解它,才能解决自己的性能优化方面的疑惑。一、定义从官方文档了解到其的定义为:阿里云分析型数据库AnalyticDB(简称ADB),是云端托管的PB级高并发实时数据仓库,是专注于服务OLAP领域的数据仓库。在数据存储模型上,采用关系模型进行数据存储,可以使用SQL进行自由灵活的计算分析,无需预…

    2022年9月17日
  • c++截取字符串[通俗易懂]

    c++截取字符串[通俗易懂]C++的string类提供了大量的字符串操作函数,提取字符串的一部分,可采用substr函数实现

    2022年5月10日
  • rtsp html播放_浏览器视频播放rtsp

    rtsp html播放_浏览器视频播放rtsp从摄像机获取的RTSP视频流直接在浏览器中播放,这里采用vlc插件进行播放,设置步骤如下1、下载32位的vlc播放器,安装时选择安装插件,安装路径不要有空格,注意64位播放器安装上也不能正常播放(我测试不能正常播放)2、注册VLC插件(否则视频无法正常显示):使用cmd运行:regsvr32D:\VideoLAN32\VLC\axvlc.dll其中D:\VideoLAN32\VLC为VLC安…

    2022年10月9日
  • 【深度学习】梯度下降算法和随机梯度下降算法「建议收藏」

    【深度学习】梯度下降算法和随机梯度下降算法「建议收藏」导语梯度是神经网络中最为核心的概念,在介绍梯度之前我们要先知道数学中的导数以及偏微分的理论概念。导数这里套用维基百科上的介绍,导数描述了函数在某一点附件的变化率,导数的本质是通过极限对函数进行局部的线性逼近,当函数\(f\)的自变量在一点\(x_0\)上产生一个增量\(△x\)时,则函数值的增量\(△y\)与自变量的增量\(△x\)的比值在\(△x\)趋于0时的极限存在,即为\(f\)在\(…

    2022年9月4日
  • 计算机 修改 虚拟ip,怎么样在电脑中设置虚拟IP地址?

    计算机 修改 虚拟ip,怎么样在电脑中设置虚拟IP地址?满意答案wtc69812020.03.01采纳率:56%等级:9已帮助:114人更改IP地址广域IP:1、如果是PPOE上网只需断开连接再重新连上就好了,服务器会从IP地址池中随机分配一个IP地址给你。2、固定IP上网那你要找运营商更改了,这样改是快不了的。局域IP:网络邻居右键属性,我的连接右键属性,打开tcp/ip更改。改网卡物理地址:1、直接改:可以在桌面上的“网上邻居”图标上单击右…

    2022年10月20日

发表回复

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

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