来源:https://blog.csdn.net/osanwenyu/article/details/48439461

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

                    本文链接:https://blog.csdn.net/oSanWenYu/article/details/48439461                

一、前言

汉字编码是让人比较头疼的一块,最近下定决定把他搞懂。网上翻了个遍,讲得详细透彻的让人头疼看不下去,讲得通俗的不够详细,只言片语。更有甚者开篇即讲Unicode是啥,多少个字符,GB2312巴拉巴拉,多少个汉字,全然不讲应用场景,不理知识接受的先后,遂结合翻看过的几篇写一写心得。

二、字符编码的发展

ASCII

--> 拓展字符集

-->GB2312(中国大陆)

-->GBK

--> unicode

1.ASCII

最早的时候计算机只在美国使用,人民解决英文与二进制的映射关系,发明了ASCII编码,将所有大小写英文字母以及常用的英文标定符号编进去。还有一些并不代表文字意义但又经常要表达的操作也加了进去,这就是控制字符,如换行、回车、制表符等等。这时发现所有的字符都编进去了,才占用了127个,每个字符占用一个字节,这是一套完美的编码方式。

2.拓展字符集

后来科技发展,计算机在世界各国普及开来,英语地区还好,直接能显示英文,非英语地区就没那么好运了。为此程序员们为自己的母语开发了自己文字与二进制的映射关系(主要是拉丁系文字的国家),从128一直占用到字节的最后一个255,这拓展的128个加上原有的128个,一共256个九叫做ASCII拓展字符集,又称IBM拓展字符集。

3.本地化(GB2312、BIG5、Shift JIS...)

再后来非拉丁系国家一看不行啊,我也要搞自己的字符集,于是百花齐放的时代来了,由于一个字节的已经被占满了,各国都采用2个字节代表自己的一个文字,如中国将第一个字节的AI~F7,第二个字节的00~FF合起来表示一个汉字,来代表7000多个汉字,直接抛弃不兼容拓展字符集,并将此字符集称为GB2312。后来又加入一些少数民族的文字、繁体字,演化出GBK。

4.Unicode一统天下

各国的字符编码都有自己的一套编码方法,彼此之间并不兼容,这显然不是最好的解决方案。为此ISO国际标准化组织提出unicode方案,以2个字节表示一个字符:

0000-007F:原基本ASCII字符集中的字符
0080-00FF:原拓展字符集中的字符
......
0600-06FF:阿拉伯文

......

4E00-9FBF:CJK 统一表意符号(包含中文字符)

......

将ASCII编码中的前128个字符保持不变,即第一个字节保持不变,后一个字节用0填充,如"A"的unicode为 0X0041,其他文字依次排在后面的空余位置,兼容世界上所有的字符!

至此字符编码演化到了最终形态。unicode与各种本地化编码共存,至于为什么共存,有太多原因,如ASCII,本来只需要1个字节表示1个"A",现在要用2个字节,容量足足翻了一番。至于GB2312,就如同国际上有了W-CDMA中国还要搞TD-CDMA一样。

唉?等等,你说UTF8?

三、unicode 与 UTF8

unicode在计算机内部(或者说单机)使用时,使用unicode是没问题的,如一个记事本,以unicode方式保存,操作系统会在记事本的开头标记一下FFEF或FEFF,以此说明是采用双字节的unicode编码,因内存读写极少出错,所以基本不会发生丢字节的情况。此时的编码即UTF-16。

那传输(联网)时呢?

考虑一个现实问题:假设你是一台计算机(小端),需要将另一台计算机(小端)传过来的unicode数据(你0x4f60   好0x597d   吗0x5417)转为字符并显示在屏幕上。

第一次,你遇到一个0x4F60,好办!显示器!给我显示”你“!

第二次,0x7d丢失,你遇到一个0x5917,也好办,”夗“!

第三次,你遇到一个0x5400,“吀”

显示结果:你夗吀  (什么鬼!)

可见,unicode在传输方面还是有缺陷的,因为每个字符看着都像是独立的,跟前后没有什么依赖关系,也没有相关标识,一旦少了一个字节,后面的所有内容都乱码了。

解决方法也显而易见,就是每个字节都标识一下,UTF-8应运而生。

四、unicode与UTF8的转换

UTF8的第一个字节的前4位用以标识本次传输的字符占用多少个字节,如1110 xxxx 标识占用3个字节。

剩余的字节都采用开头为10的方式,如10xx xxxx。

比如“ 直 ”, unicode编码: 76f4 ,   相应二进制   0111 0110 1111 0100

因为汉字的unicode固定是2个字节,而转成utf8则是固定3个字节。

1110 ____,  10__ ____, 10__ ____

将“ 直” 0111 0110 1111 0100 连续填入:

二进制 : 1110 0111,  1001 1011, 1011 0100, ,十六进制 : e79b94,此为UTF-8

五、被滥用的UTF-8

UTF-8一开始只用于网络传输,并不作为本地存储形式,后来程序员们因为懒、麻烦,不会引起其他问题等种种不啦不啦原因,直接将UTF-8用于存储。

如何知道文件用的是什么方式编码的呢?

二进制打开文件,开头字节能区分。

开头字节

Charset/encoding

EF BB BF

UTF-8

FE FF

UTF-16/UCS-2, little endian

FF FE

UTF-16/UCS-2, big endian

FF FE 00 00

UTF-32/UCS-4, little endian.

00 00 FE FF

UTF-32/UCS-4, big-endian.

开头字节 Charset/encoding
\ ANSI(中文是GB2312)
   
   

六、要点

unicode能表示所有的字符,任何其他的编码方式都是针对特定字符的。

unicode在本地的形式是UTF-8,UTF-16,UTF-32,网络传输形式只能是UTF-8

开头字节能区分编码方式

Unicode、UTF8、GB2312、ANSI的更多相关文章

  1. 字符编码简介:ASCII,Unicode,UTF-8,GB2312

    字符编码简介:ASCII,Unicode,UTF-8,GB2312 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和 1两种状态,因 ...

  2. JAVA js的escape函数、解析用js encodeURI编码的字符串、utf8转gb2312的函数

    在使用webView时,如果url中参数有中文的话,拦截到的字符串就会类似这样的:http://api.letstar.cn/zq/news.html?id=20&cupName=%E6%B5 ...

  3. [Python] 中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题

    最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下 ...

  4. 编码方式ASCII、GBK、Unicode、UTF-8比较

    文章内容深度较浅,详细了解可到下链接:https://blog.csdn.net/QuinnNorris/article/details/78705723; 总结了以下几种编码方式: ASCII.GB ...

  5. ASCII、ANSI、GB2312、Unicode、UTF-8之间的关系

    1.ASCII码: ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统.它主要用于 ...

  6. 编码格式简介:ASCII码、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM头

    编码格式简介:ASCII码.ANSI.GBK.GB2312.GB18030和Unicode.UTF-8,BOM头 二进制: 只有0和1. 十进制.十六进制.八进制: 计算机其实挺笨的,它只认识0101 ...

  7. ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE

    http://www.chinaz.com/web/2012/1119/282540.shtml 编码一直是让新手头疼的问题,特别是 GBK.GB2312.UTF-8 这三个比较常见的网页编码的区别, ...

  8. [转]各种编码ANSI、GB2312、GBK、GB18030、UNICODE以及UTF-8傻傻分不清!

    计算机编程中的编码一直是让新手非常头疼的问题,特别是 GBK.GB2312.UTF-8 这三个比较常见的网页编码的区别,更是让许多新手晕头转向,怎么解释也解释不清楚,看一遍貌似懂了,但实际使用的时候又 ...

  9. Ansi、GB2312、GBK、Unicode(utf8、16、32)

    关于ansi,一般默认为本地编码方式,中文应该是gb编码 他们之间的关系在这边文章里描写的很清楚:http://blog.csdn.net/ldanduo/article/details/820353 ...

  10. 各种编码UNICODE、UTF-8、ANSI、ASCII、GB2312、GBK详解

    来自:http://blog.csdn.net/lvxiangan/article/details/8151670 ------------------------------------------ ...

随机推荐

  1. 基于python tkinter的课堂点名小程序

    import datetime import json import os import random import tkinter as tk import openpyxl # 花名册文件名很多人 ...

  2. TypeError 之 Cannot convert undefined or null to object

    分享一个今天遇到的一个bug , 希望对你也有用. 1.Object.keys()中传错了参数 2.由于undefined和null无法转成对象,所以如果它们做为Object.assign()的参数( ...

  3. Update LateUpdae FixedUpdate

    这个问题本来是在研究动画系统时遇到的:OnAnimatorMove在Animator.Update()调用,那这个Animator.Update是什么时候调用的呢. Animator Componen ...

  4. 使用Docker构建PHP7.4 + Swoole + Redis镜像

    使用Docker构建PHP7.4 + Swoole + Redis镜像 Docker是一个用于开发,交付和运行应用程序的开放平台.开发者可以利用Docker来快速交付,测试和部署代码,从而大大减少编写 ...

  5. Python 中的数字到底是什么?

    花下猫语:在 Python 中,不同类型的数字可以直接做算术运算,并不需要作显式的类型转换.但是,它的"隐式类型转换"可能跟其它语言不同,因为 Python 中的数字是一种特殊的对 ...

  6. 使用java8的方法引用替换硬编码

    背景 想必大家在项目中都有遇到把一个列表的多个字段累加求和的情况,也就是一个列表的总计.有的童鞋问,这个不是给前端做的吗?后端不是只需要把列表返回就行了嘛...没错,我也是这样想的,但是在一场和前端的 ...

  7. Python学习—Anaconda详细 下载、安装与使用,以及如何创建虚拟环境,不仅仅只有安装步骤哦

    上一期我们介绍了Python.Pycharm.Anaconda三者之间的关系以及使用,这一期主要详细介绍如何在Windows上下载和安装工具Anaconda,然后使用其自带的conda管理不同项目的虚 ...

  8. leetcode刷题-80.删除排序数组中的重复项 II

    题目 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. ...

  9. LC算法技巧总结(二):双指针和滑动窗口技巧

    我把双指针技巧再分为两类,一类是「快慢指针」,一类是「左右指针」.前者解决主要解决链表中的问题,比如典型的判定链表中是否包含环:后者主要解决数组(或者字符串)中的问题,比如二分查找. 一.快慢指针的常 ...

  10. pytest测试框架 -- setup和teardown等

    一.用例运行级别 1.函数级别(setup.teardown 或 setup_function.teardown_function): 仅对处于同作用域的测试函数有效(该函数定义不在类中,则对非类中测 ...