关于坑爹的编解码问题

关于坑爹的编解码问题

编解码问题从来都是搞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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Adobe Dreamweaver 2021下载安装教程

    Adobe Dreamweaver 2021下载安装教程软件介绍AdobeDreamweaver2021是专业的网站设计软件,使用可为处理各种Web文档提供灵活的环境。Dreamweaver2021一款非常受欢迎的网页设计软件,是该系列的全新版本,可以帮助广大学生、程序员制作出精美的网页,在全新的Dreamweaver2021版本中,在其优秀的功能上带来了更多的改进和优化,拥有无缝实时视图编辑功能,在以往用户需要切换到单独的编辑模式来预览网站,现在仅需一键即可预览和更改网页,还支持Windows的多显示器方案,为用户带来了更加整洁主界面,并且修改了十多个

  • es7学习笔记 cpu负载不均衡、超长fullGC、大量400报错[通俗易懂]

    es7学习笔记 cpu负载不均衡、超长fullGC、大量400报错[通俗易懂]ElasticSearch负载不均衡现象:往es7集群中推数时,发生如下情况接口出现很多400 发现集群中某台机器cpu被怼爆 发生fullGC产生400报错的原因是es7做了熔断优化,当jvm内存使用超过阈值,为了避免丑陋的oom,会直接限流并抛出EsRejectedExecutionException。我们强硬的关掉了这个配置,因为我们的推数有失败重试。产生fullGC是因为一个bulk批处理的数据量太大,我们一个文档1.5M,800个文档作为一批,两个线程并行推,jvm内

  • docker(2)CentOS 7安装docker环境[通俗易懂]

    docker(2)CentOS 7安装docker环境[通俗易懂]前言前面一篇学了mac安装docker,这篇来学习在linux上安装docker环境准备Docker支持以下的CentOS版本,目前,CentOS仅发行版本中的内核支持Docker。Doc

  • 漫画:独立女性真的更讨人喜欢吗?

    今天给大家推荐一篇反套路的漫画 谁说女主都要是清纯白莲花? 《总裁想静静》 漫画已经完结,看起来更过瘾! 第一话 第二话 第三话 原文始发于微信公众号(全栈程序员社区):漫画:独立…

  • activiti工作流框架_springboot工作流框架

    activiti工作流框架_springboot工作流框架工作流Activiti是一个项目的名称,Alfresco软件在2010年5月17日宣布Activiti业务流程管理(BPM)开源项目的正式启动,其首席架构师由业务流程管理BPM的专家TomBaeyens担任。Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN2.0标准,包括支持对象管理组(OMG),面对新技术的机遇,…

  • 算法的时间复杂度和空间复杂度-总结[通俗易懂]

    算法的时间复杂度和空间复杂度-总结[通俗易懂]算法的时间复杂度和空间复杂度1、时间复杂度(1)时间频度一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(

发表回复

您的电子邮箱地址不会被公开。

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