计算机编码总结

英文字母和中文汉字在不同字符集编码下的字节数

英文字母:

字节数 : 1;编码:GB2312

字节数 : 1;编码:GBK

字节数 : 1;编码:GB18030

字节数 : 1;编码:ISO-8859-1

字节数 : 1;编码:UTF-8

字节数 : 4;编码:UTF-16

字节数 : 2;编码:UTF-16BE

字节数 : 2;编码:UTF-16LE

中文汉字:

字节数 : 2;编码:GBK

字节数 : 2;编码:GB18030

字节数 : 1;编码:ISO-8859-1

字节数 : 3;编码:UTF-8

字节数 : 4;编码:UTF-16

字节数 : 2;编码:UTF-16BE

字节数 : 2;编码:UTF-16LE

编码发展历史简介

第一阶段 ASCII

在计算机中,所有的数据只可能是0或者1(用高电平和低电平分别表示1和0),那么我们通常看到的字符也就只能用0和1来表示呀。于是科学家们(这里指的是美国的科学家)就想出一个办法,把一个特定的数字对应一个特定的字母进行存储和传输,比如我需要存储字母a,那么我存入一个数字97(即在计算机中存入二进制(01100001),这个过程叫做编码(encode),而我们在读取数据的时候,当遇到97时,我们就让计算机显示字母a,这个过程叫做解码(decode)。

为了大家在数据传输的时候不至于产生误会,那么我们需要让所有的人都使用数字97来代表字母a,所以需要制定一份标准(即码表),最开始的这个标准叫做ASCII码表。

规则

  • 所有的控制字符(比如CR回车、DEL删除等)编码在0-31范围以及127中。
  • 把所有的标点符号,英文大小写全部放在32-126范围中。
  • 防止以后出现需要补充的情况,把128-255位这么多位置留出来,应该足够用了吧!所以设置一个字节8位二进制,把这个标准叫American
    Standard Code for Information Interchange(美国标准信息交换代码,简写为ASCII),标准制定结束。

等等,我们的中文字呢?

美国的"砖家"没有考虑那么久远呢!这就是后面出现那么多问题的根源所在啊。

实现方式

第一位始终未0,后面7位表示0-127的范围,一个数字对应一个字母或者标点符号,亦或者控制符号,即所有的ASCII码的统一形式为0xxxx xxxx。

第二阶段 GB2312,GBK, BIG5 Latin1, ISO-8859-1, JIS, ANSI...

计算机技术到了欧洲,欧洲人发现怎么我们的那么多符号没有编进去啊!

所以欧洲"砖家"坐到了一起,开始讨论。

发现既然美国人把第一位流出来了,那么我们就用128-255的位置好了。

规则

128-159之间为控制字符,160-255位文字符号,其中包括了西欧语言、希腊语、泰语、阿拉伯语、希伯来语。

刚好把美国人给的空间全部用完,世界真美好,谢谢美利坚预留的每一个位置。

砖家们决定把他们的编码名称叫做Latin1,后面由于欧洲统一制定ISO标准,所以又有了一个ISO的名称,即ISO-8859-1。

实现方式

  • 0-127的所有位置不动,那么可以兼容ASCII,二进制位0xxx xxxx
  • 128-255位置全部用完,二进制位1xxx xxxx

    由于所有的位置全部用完,而欧元符号实在指定标准之后才出现的,所以在这个码表中连欧洲人自己的货币符号都没有办法放进去。

计算机技术当然也传到了亚洲大地,比如中国。

中国砖家们坐在一起发现,美国人搞的这个东西真的有问题,预留才128-255的空间,可是我们的汉字个数远远超出了这个数目啊,怎么办??

后面聪明的中国砖家们发现,只能使用2个字节了,否则真的搞不定。

由于必须和美国原来制定的ASCII不冲突,所以指定了如下规则

规则

  • 如果一个字节中第一位为0,那么这就是一个ASCII字符。
  • 如果一个字节中第一位为1,那么这个是汉字,认定需要2个字节才表示一个编码的文字。

    把这个码表叫GB2312

    这个码表中包含汉字6763个和非汉字图形字符682个。

    还有很多的空间没有用到,索性全部预留了吧。

    实现方式

  • 0xxxxxxx:表示为ASCII字符

    -1xxxxxxx 1xxxxxxx:表示为汉字

后来,中国砖家们发现,很多的不常用汉字没有在码表中,于是添加了很多的汉字进去,这个编码叫做GBK,实现方式和GB2312是完全一样的,兼容GB2312,当然也兼容ASCII。

实现方式

  • 0xxxxxxx:表示为ASCII字符

    -1xxxxxxx xxxxxxxx:表示为汉字

后面再次添加更多的字符进去,再次命名为GB18030,兼容GBK。由于汉字很多,2个字节并不能完全包括进去,所以GB18030采用2\4位混编的形式。

当然计算机也传到了日本(JIS)、韩国、台湾(BIG5)等等地方,大家全部发挥自己的聪明才智,各自实现了自己的编码。这些编码都与ASCII兼容,但是相互之间不兼容。

使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码,又称为"MBCS(Muilti-Bytes Charecter
Set,多字节字符集)"。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS
编码,所以在中文 windows下要转码成gb2312,gbk只需要把文本保存为ANSI编码即可。 不同ANSI编码之间互不兼容

第三阶段

随着通讯越来越多,而老美发现在自己公司需要国际化的时候,自己原来埋的这个雷真的害了自己。

于是乎,开始研讨把世界上几乎所有文字全部放在一个码表中,而这个包罗万象的码表就叫做Unicode,即万国码。

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。

实际上,在软件制造商的协会(unicode.org)在做这个工作时,国际标准化组织(ISO)在做同样的事情,最后大家都意识到世界上并不需要两个不同的万国码,于是大家坐在一起合并研究的成果,最后的结果就是现在的Unicode。

各个编码及其范围

ASCII

编码范围00-7F,其中00-1F、FF为控制字符。其它为英文字母、数字、标点符号。

Latin1

编码范围00-FF,其中00-7F同ASCII,80-9F为控制符、9F-FF为字母和标点符号.

CP1252

微软的企业标准,补充了一些符号和欧元符号,为Latin1的超集。

GB2312

编码范围为A1A1-F7FE(剔除xx7F),共23940个码位。其中很多区间没有用到,而汉字使用的区间为B0A1-F7FE,其他为标点符号和特殊字符。

除常用简体汉字字符外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符,未收录繁体中文汉字和一些生僻字。

对汉字进行了分区管理,其中第一个字节为区位码,包括下面区位。

01-09区为特殊符号。

16-55区为一级汉字,按拼音排序。

56-87区为二级汉字,按部首/笔画排序。

10-15区及88-94区则未有编码。

第二个字节为位字节,01-94总计94个。

为什么实际选择不是01-5E,而是选择A1-F7的位置呢?

因为英文可见字符区间为20-7F,加上128(也就是最高位为1)后得到的取件即是A1-FE

区位码使用了0xA1-0xF7(把01-87区的区号加上0xA0),位字节使用了0xA1-0xFE(把01-94加上 0xA0)

GBK

编码范围为8140-FEFE,兼容GB2312,仍然有部分区间没有用到。

GBK也支持希腊字母、日文假名字母、俄语字母等字符,但不支持韩语中的表音字符(非汉字字符)。GBK还收录了GB2312不包含的 汉字部首符号、竖排标点符号等字符。

CP936

CP936是微软指定的标准,属于企业标准,和GBK的有些许差别,绝大多数情况下可以把CP936当作GBK的别名。

BIG5

Big5是双字节编码,高字节编码范围是0x81-0xFE,低字节编码范围是0x40-0x7E和0xA1-0xFE。和GBK相比,少了低字节是0x80-0xA0的组合。0x8140-0xA0FE是保留区域,用于用户造字区。

Big5收录的汉字只包括繁体汉字,不包括简体汉字,一些生僻的汉字也没有收录。

CP950

微软的企业标准,可以理解为是对 Big5的扩展。

GB18030

编码范围同GBK,补充了更多的字符,由于Unicode开始流行且GB18030补充的字符都比较生僻,所以实际使用上基本是GBK。

GB18030编码是变长编码,有单字节、双字节和四字节三种方式。GB18030的单字节编码范围是0x00-0x7F,完全等同与ASCII;双字节编码的范围和GBK相同,高字节是0x81-0xFE,低字节的编
码范围是0x40-0x7E和0x80-FE;四字节编码中第一、三字节的编码范围是0x81-0xFE,二、四字节是0x30-0x39。

Unicode

中文的编码范围为4E00-9FCF,其中9FC4-9FCF之间的区间没有使用。

一个蛋疼的问题就是这个区间全部都是文字,中文标点没有包含在其中,中文标点散落在各个位置。详细请看http://blog.chinaunix.net/uid-12348673-id-3335307.html。

一些特殊的文字和中文部首以及一些特殊符号也不在此范围内,详细情况可以参考网址:http://www.cnblogs.com/sosoft/p/3456631.html

编码方面的一些概念

大尾(big endian)和小尾(little endian)

大尾和小尾是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。

BOM

UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

Unicode规范中推荐的标记字节顺序的方法是BOM,即Byte Order Mark。BOM是一个有点小聪明的想法:

在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK
SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO
WIDTH NO-BREAK SPACE"。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK
SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB
BF开头的字节流,就知道这是UTF-8编码了。

Unicode的实现方式

Unicode只是进行了编码,也就是说只是一个码表,至于具体怎么实现,并没有规定。

下面是Unicode的几种实现方法。

UTF-8

范围 字节数 存储格式
0x0000~0x007F (0 ~ 127) 1字节 0xxxxxxx
0x0080~0x07FF(128 ~ 2047) 2字节 110xxxxx 10xxxxxx
0x0800~FFFF(2048 ~ 65535) 3字节 1110xxxx 10xxxxxx 10xxxxxx
0x10000~1FFFFFF(65536 ~ 2097152) 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0x2000000~0x3FFFFFF 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0x4000000~0x7FFFFFFF) 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

理论上说,UTF-8并没有大小尾的困扰,所以并不需要BOM。

但是一些Windows应用会指定大小尾,比如Notepad,而且Excel在没有指定BOM的UTF-8文件进行读取时会使用Windows的codepage,从而出现错误。

UTF-16

在Unicode基本多文种平面定义的字符(无论是拉丁字母、汉字或其他文字或符号),一律使用2字节储存。而在辅助平面定义的字符,会以代理对(surrogate pair)的形式,以两个2字节的值来储存。

UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。

可以认为UTF-16是下面介绍的UCS-2的父集。在没有辅助平面字符(surrogate code
points)前,UTF-16与UCS-2所指的是同一的意思。但当引入辅助平面字符后,就称为UTF-16了。现在若有软件声称自己支援UCS-2编码,那其实是暗指它不能支援在UTF-16中超过2bytes的字集。对于小于0x10000的UCS码,UTF-16编码就等于UCS码。

如果一个UTF-16文件没有指定BOM,默认应该是UTF-16BE,但是在Intel x86中却是UTF-16LE。所以在现实世界中有很多的没有指定大小尾的UTF-16却是UTF-16LE。

UTF-32

每一个Unicode码位使用恰好32位元。可以粗暴的认为UTF-32和下面要介绍的UCS-4是等同的。

UCS-2

采用2个字节,定长的表示每一个字符,所以总计可以表示2^16个字符。

UCS-4

UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行(rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。

group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。

将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。

编码转换

请参考

字符编码之UCS-2与Utf-8

UCS-2和UTF-8的互相转换

操作系统使用编码

从Windows2K开始,Win的系统内核开始完全支持并完全应用Unicode编写,所有ANSI字符在进入底层前,都会被相应的API转换成Unicode。

Linux 服务器上 UCS-2 编码方式与 Winodws 不一致,以下是有关两个平台 UCS-2 编码的潜规则:

  1. UCS-2 不等于 UTF-16。 UTF-16 每个字节使用 ASCII 字符范围编码,而 UCS-2 对每个字节的编码可以超出 ASCII 字符范围。UCS-2 和 UTF-16 对每个字符至多占两个字节,但是他们的编码是不一样的。
  2. 对于 UCS-2, windows 下默认是 UCS-2LE。用 MultibyteToWidechar(或者A2W)生成的是 UCS-2LE 的 unicode。windows记事本可以将文本保存为 UCS-2BE,相当于多了层转换。
  3. 对于 UCS-2, linux 下默认是 UCS-2BE。用iconv(指定UCS-2)来转换生成的是 UCS-2BE 的 unicode。如果转换windows平台过来的 UCS-2, 需要指定 UCS-2LE。
  4. 鉴于windows和linux等多个平台对 UCS-2 的理解不同(UCS-2LE,UCS-2BE)。MS 主张 unicode
    有个引导标志(UCS-2LE FFFE, UCS-2BE FEFF),以表明下面的字符是 unicode 并且判别 big-endian 或
    little-endian。 所以从 windows 平台过来的数据发现有这个前缀,不用慌张。

对于JAVA/.NET/Python等这些“新”的语言来说,内置的字符串所使用的字符集已经完全是Unicode最重要的是,世界上大多数程序用的字符集都是Unicode,因为Unicode有利于程序国际化和标准化。

Python与编码

我会接着写另外一篇文章。

参考资料

    1. http://blog.chinaunix.net/uid-12348673-id-3335304.html
    2. http://demon.tw/programming/utf-16-ucs-2.html
    3. http://cryolite.iteye.com/blog/505011
    4. http://blog.chinaunix.net/uid-10468429-id-2953054.html

原文地址:https://www.cnblogs.com/Free-Thinker/p/8309785.html

时间: 2024-10-14 13:54:41

计算机编码总结的相关文章

计算机编码中的换行 CR与LF

以下的文字为转载,但是有错误的地方,博主自行进行了修正和补充,用红色标示. 原文地址在这里. ------------ 转载起始 ------------- "回车"(Carriage Return) 和 "换行"(Line Feed) 这两个概念的来历和区别. 1. 起源:电传打字机 在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33,Linux/Unix下的tty概念也来自于此)的玩意,每秒钟可以打10个字符.但是它有一个问题,就是

计算机编码

编码是信息从一种形式或格式转换为另一种形式的过程也称为计算机编程语言的代码简称编码.用预先规定的方法将文字.数字或其它对象编成数码,或将信息.数据转换成规定的电脉冲信号.编码在电子计算机.电视.遥控和通讯等方面广泛使用.编码是信息从一种形式或格式转换为另一种形式的过程.解码,是编码的逆过程. ASCII 我们日常接触到的文件分ASCII和Binary两种.ASCII是"美国信息交换标准编码"的英文字头缩写,可称之为"美标".美标规定了用从0到127的128个数字来代

计算机编码问题

一.二进制,位,字节.字符 我们都知道,在计算机内部,数据都是以二进制的形式存储,所有的信息最终都表示为一个由0和1组成的字符串,每一个二进制位都是只有0或者1两种状态,每一个0或者0称为位(bit),然后规定每八个二进制位为一个单位,为一个字节(byte),现在可以明白了,位和字节都是内存的空间单位,或者说是计算机中数据量的计量单位,如 int 为32位,也可以说是4字节. 字符就是在计算机显示器给我们显示的一个个文字或者符号,比如:A.B.C,你,好,&,+等都是一个字符 二.编码 刚才说的

计算机编码方式

首先需要弄明白一件事,计算机只能识别0,1.因此字符什么的需要编码进行存储. 计算机是由老外发明的,他们可没有什么汉字 ,只有ABCD....,所以呢,最早的编码 是ASCII编码,最开始是给128个字符进行编码. 但这显然是不行的啊,世界上除了英语,还有那么多其他语言,因此ASCII码显然不适合 这种情况. 于是又有了Unicode编码方式,俗称万国码,可以存储好几万个字符.但是又有新的问题 出现了,Unicode码不适合存储啊,因为Unicode是定长编码,非常浪费存储空间, 这里又有了一种

计算机编码--为什么整数中负数的除法和右移不是一回事

缘起 最近在看卡耐基梅隆大学的[深入理解计算机系统实验]之datalab时,遇到一个题目: 1 /* 2 * divpwr2 - Compute x/(2^n), for 0 <= n <= 30 3 * Round toward zero 4 * Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2 5 * Legal ops: ! ~ & ^ | + << >> 6 * Max ops: 15 7 * Rating

漫谈计算机编码:从ASCII码到UTF-8

第一阶段 盘古开天辟地--ASCII码 计算机大家都知道,本质是二进制运算和存储.在计算机中人类的几乎所有文字和字符都没法直接表示,所以美国人在发明计算机的时候为了让计算机可以用于保存和传输文字,就发明了ASCII码(American Standard Code for Information Interchange,美国信息交换标准代码),用128个数字分别映射到美国人常用的一些字符,一个字符只占用一个字节.这样一来就满足了美国人的交流需要. 第二阶段  军阀混战之战国七雄--GBK 但是计算

计算机 编码 解码

目录 1 字符 & 编码 2 记事本下的乱码 3 UTF-8解码过程 4 UTF-16解码过程 5 ISO-8859-1 6 byte范围 在阅读本文章之前,我建议你首先看阮一峰的博客:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 1 字符 & 编码 字符: 是文字和符号的总称.一个汉字.标点符号.英文字母.数字,这都是字符 字符集: 是多个字符的集合.我们可以理解为一本大字典.字符集种类很多,每个字

unicode,utf-8,ASCLL计算机编码原理

一.字符编码问题先介绍一下字符编码问题 1.ASCLL与GB2312 由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母.数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122. 但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去. 国标码是汉字的国家标准编码,目前主要有GB2312.GBK.GB18030三种. GB2312

深入浅出计算机编码、乱码问题

原创: 王利涛  宅学部落  今天 很多新手在编写程序.使用软件打开文档或者浏览网页时,经常遇到乱码显示.全角半角的问题. 网上也有很多解决的方法,大部分都是跟编码方式和设置有关:比如Unicode.UTF-8.ASCII码.GB2312...,令人眼花缭乱,今天就给大家理一理它们之间的关系. 计算机只认识0和1这两个数字,我们输入的程序代码.文字都要经过编码,然后才能被计算机识别.解析和存储.早期的计算机环境是主要是英文,我们对构成英文的这些基本字母:拉丁字母编码就可以了,比如ASCII码.