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

指定utf8之后为什么还是‘’ascii_浅谈对ASCII、UNICODE、LANTIN1、UTF81632的认识...

现在java入门大家基本上都是在说springmvc,mybatis,springboot,springcloud等等的应用框架,说起来一
现在java入门大家基本上都是在说springmvc,mybatis,springboot,spring cloud 等等的应用框架,说起来一套一套的,似乎很高端的样子,对方听起来一愣一愣的。但对底层的数据结构、编码、算法等这类有就所偏弱了。本人也有同样问题,我是以java技术出身,没有正统的学习过汇编、C这些比较底层的言语。对一基很基础的知识理论并不理解和透彻。之前对编码知识这块都是一知半解。所以近两天专门查阅了一些基础知识,对ascii、unicode、lantin-1、utf-8、utf-16/32编码知识补习了一下。

趁人未老,还没把知识忘记,现在归纳总结下自己的理解。本文章节包括如下几点:

  1. 字节基本知识
  2. ASCII编码
  3. UNICODE编码
  4. UTF-8编码
  5. UTF-16/32编码
  6. LANTIN-1编码

一、字节基本知识

理解ascii,unicode等编码,为什么先理解字节的基本知识了?是因为了解基本知识后有助于理解相关编码知识。 甩个百度百科链接自己看 https://baike.baidu.com/item/%E4%BD%8D%E3%80%81%E5%AD%97%E8%8A%82%E3%80%81%E5%AD%97/15650262

最终要知道是 1字节 = 8位 。举例这里有8个数字(0或1)组成的就是1字节 ,如 00000010 。 而1字节能表示的数值范围是 0 ~ 255,计算方法是 “2的8次方 ”。

二、ASCII编码

  • 计算机是个文盲,只认识0和1。如果我们把 001010100010100100101010 输进计算机,它马上能知道这个数字转成10进制是9527(这个9527是瞎写的)。但是我们农民百姓怎么知道00101010001010010010 1010这个是什么鬼。所以呢,歪果仁就制定了一套规则,把字母、数字,符号都编个号,比如大写'A'是65,数字’1‘是49,转成二进制就是 65 = 0100 0001, 49 = 0011 0001 。
  • 歪果仁所用的英语,也就ABC + 123 这么几个字组成,所以当时只定了127个字符对应关系,也就是ASCII编码。127个字符的是基础ascii编码,也就是最早的编码规范了。引用百度百科(https://baike.baidu.com/item/ASCII/309296?fr=aladdin)的一句话: ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符

基础ascii码的字节表示方式是 : 0XXX XXXX (见上述百度百科描述)。 第一位必须为0,剩下的7位二进制范围是0 ~ 127。 一个字节的范围是0 ~ 255,现在基础ASCII码用到了0 ~ 127,而-1~ -128 范围干嘛用了呢?还是百度百科的一句话(如果描述不对,就找百度说去吧):

高位128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号 基础ascii和扩展ascii的分布情况用图表示:
b726f029ebd908b9956ad483412ee3e3.png

小结: 1. ascii是单字节,在 0 ~ 127 范围是基础码,在128 ~255 是扩展码; 2. 在0 ~ 127范围内是全球标准,所有单字节编码(latin-1),或长度可变编码(utf-8)都兼容。而 -1 ~ -128 范围则不兼容,每种编码规范所定义的标准都不同;

二、UNICODE规范(这里没用‘编码’二字)

歪果仁图样图森破,制定ASCII编码时只考虑了ABC,但没有考虑到非英文国家的文字,所以光有ascii码还不够,这就引出了其他编码的诞生。还是引用百度百科来解释UNICODE的诞生原因(https://baike.baidu.com/item/Unicode/750500?fr=aladdin)

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),0 - 255被用来表示大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。 如果要表示中文,显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。 类似的,日文和韩文等其他语言也有这个问题。为了统一所有文字的编码,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

目前,我没有了解UNICODE编码如何去设计每个字符的编码规则,所以需要大家自行搜索。

百科 https://baike.baidu.com/item/Unicode/750500?fr=aladdin

这里简单归纳一下我对UNICODE的理解:

  1. 它为每种语言中的每个字符设定了统一并且唯一的二进制编码;
  2. 它只是一个规范,并没有告诉大家如何存储(这点是关键)。而UTF-8,UTF-16,UTF-32是实现存储UNICODE编码的三种方式。

而有些细心的朋友会问:为什么WINDOWS下文本编辑器‘另存为’时(下图),可以选择UNICODE编码呢,不是说UNICODE是一个规范吗?

77a10636527e0d8ef5a9df9f7d778c9b.png

这个问题,我当时也有同样的疑问。老夫花了一些时间去搜索答案,自己也验证了一下

WINDOWS文本编辑器的‘另存为’时的Unicode 就是 UTF-16 LE 编码;Unicode big endian 就是UTF-16 BE 编码。

用windows记事本‘另存为’UNICODE编码,用emeditor打开,显示的是UTF-16 LE。

3c2d096a0da706775fd3566155e949f7.png

小结: 1. UNICODE是一种规范,为全球定义了每一个字符的唯一的二进制编号,但没有告诉大家如何去存储这个编号。

三、UTF-8编码

UNICODE规范的实现方式常见有三种:UTF-8、UTF-16、UTF-32。先说UTF-8吧。 UTF-8:UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,由Ken Thompson于1992年创建,现在已经标准化为RFC 3629,UTF-8用1到4个字节编码Unicode字,是可变长度的编码方式。

6770fc8a2d37d05da8d037370797701b.png

见上图百度百科中的UTF-8转换表,图中可以看出在不同范围内UNICODE的字符,UTF-8所存储的字节数都不同,比如 0000 ~ 007F ,只需要 1 Byte,0080 ~ 07FF 需要2 Byte。 有些字符是一个字节,有些字符是两个字节,有些字符是三个字节。如果假如有三个字节或更多 XXXXXXXX|XXXXXXXX|XXXXXXXX (竖线是为了更好区分),那计算机怎么知道这三个字节是解析成 一个字符(3byte),还是一个字节(1 Byte) + 一个字节(2 Byte)呢? 以百度百科的描述:

UTF-8编码规则:如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。
  • 0xxxxxxx:单字节编码形式;
  • 110xxxxx 10xxxxxx:双字节编码形式;
  • 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式;
  • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式;

数前面有几个“1”,如果“0”开头,则是单字节; 如果有两个“1”,则是双字节,后面一个字节必须是“10”开头。如下图,相同颜色的为同一字符。

7cae5e4ca82f81824de89e888001b04a.png

小结: 1. UTF-8 是UNICODE的实现存储方式之一; 2. UTF-8 是长度可变的编码,是现互联网上用的最普遍的编码;

四、UTF-16编码

UTF-16是UNICODE编码实现方式之一,该编码长度既是可变,亦是固定:采用存储的字节长度,要么是2Byte ,要么是4Byte。

0508cfa1abcb71183086ee47e7d0aecd.png

UTF-16编码分为 UTF-16 little endian(LE) 和 UTF-16 big endian (BE): 1. Little endian:将低序字节存储在起始地址 2. Big endian:将高序字节存储在起始地址 这里涉及了一个概念,就是字节序,看百度百科的描述:(https://baike.baidu.com/item/%E5%AD%97%E8%8A%82%E5%BA%8F):

字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。 BIG-ENDIAN、LITTLE-ENDIAN跟CPU有关,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN。IA架构(Intel、AMD)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器是Big-Endian。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的,在Internet的网络字节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。

查找了一些相关文章或技术贴,有一段写的相对比较容易理解的我就直接截图,不再重复描述说明,内容源于 https://blog.csdn.net/li123128/article/details/80709027

9e1ab2170e648560c2c21a2bc36b5b02.png

小结: 1. UTF-16 是UNICODE的实现存储方式之一; 2. UTF-16 为分little endian 和 big endian 两种方式;windows 采用是 utf-16 le ,而 mac 采用是 utf-16 be; 3. UTF-16 编码采用2byte 或 4byte 的字节来存储字符;

五、UTF-32编码

理解了ASCII、UNICODE、UTF-8 、UTF-16,那么UTF-32就没什么好讲的了。百度百科上描述的也很简单:

UTF-32 (或 UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位元。其它的Unicode transformation formats则使用不定长度编码。因为UTF-32对每个字符都使用4字节,就空间而言,是非常没有效率的。特别地,非基本多文种平面的字符在大部分文件中通常很罕见,以致于它们通常被认为不存在占用空间大小的讨论,使得UTF-32通常会是其它编码的二到四倍。虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。

小结: 1. 每个字符都采用 4byte 字节来存储,浪费存储空间;

六、Latin-1

还是百度百科的描述(https://baike.baidu.com/item/latin1/1183590?fr=aladdin):

Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。

小结: 1. latin-1 就是 iso-8895-1; 2. latin-1 是单字节编码; 3. 在 0 ~ 127 范围与 ascii 的一致;在128 ~ 255 则不同; 4. 因为latin-1(ISO-8859-1)编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。

七、收尾

  1. 参考了网上大神们的总结和分享。https://blog.csdn.net/guxiaonuan/article/details/78678043 https://blog.csdn.net/hezh1994/article/details/78899683 https://blog.csdn.net/Deft_MKJing/article/details/79460485 https://www.cnblogs.com/tk55/p/6592673.html https://blog.csdn.net/tcf_jingfeng/article/details/80134600 https://blog.csdn.net/qq_36761831/article/details/82291166 中间还参考了其他的文章,很多都记不清了,所以就不一一贴出。
  2. 本文多方引用了百度百科的解析,并不是它解析或描述的很好,最主要是我认为百科给出的定义内容是相对个人网站或个人撰写的文章而言,是相对比较可信的。
  3. 写一编总结不易,前前后后花了不少时。一是要自己理解后再写下来;二是不能只单看某一编文章就下定论,需多方参考、对比。
  4. 理解了ASCII ,UNICODE 之后,再去了解中文,法文,俄文等编码会更容易理解。

如有错漏,请纠正!



推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 2018深入java目标计划及学习内容
    本文介绍了作者在2018年的深入java目标计划,包括学习计划和工作中要用到的内容。作者计划学习的内容包括kafka、zookeeper、hbase、hdoop、spark、elasticsearch、solr、spring cloud、mysql、mybatis等。其中,作者对jvm的学习有一定了解,并计划通读《jvm》一书。此外,作者还提到了《HotSpot实战》和《高性能MySQL》等书籍。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • “你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬” ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • Centos7搭建ELK(Elasticsearch、Logstash、Kibana)教程及注意事项
    本文介绍了在Centos7上搭建ELK(Elasticsearch、Logstash、Kibana)的详细步骤,包括下载安装包、安装Elasticsearch、创建用户、修改配置文件等。同时提供了使用华为镜像站下载安装包的方法,并强调了保证版本一致的重要性。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
author-avatar
尕心疼TammyY
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有