位,字,字节,字符,编码,ASCII,UTF,GB精析

本文介绍了计算机中数据的基本单位位、字节、字的概念及其重要性,并详细解析了ASCII、GB系列编码、Unicode及其转换格式(UTF)等字符编码方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/he_jian1/article/details/43016325
http://www.cnblogs.com/kex1n/p/4138427.html

一 贴近硬件的字,字节,字长

在性能测试当中,任何脱离底层的内容,对于性能测试来讲,都是不完整的,任何程序,何何中间件如果没有操作系统及计算机支撑,都是毫无意义的,因为在计算机世界里,有一些概念需要我们能够掌握和了解,比如说:位,字,字长

首先说一下位:
位表示的是二进制位,一般称为比特,是计算机存储的最小单位,类似于(两,公斤,克)的概念,比如:11010100是一个8位二进制数。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以表示00、01、10、11四种(22)状态;三位二进制数可表示八种状态(23)

字节(byte):
字节来自英文Byte,音译为“拜特”,习惯上用大写的“B”表示。
字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)。八位二进制数最小为00000000,最大为11111111;通常1个字节可以存入一个ASCII码,2个字节可以存放一个汉字国标码。

字:
计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。一个字通常由一个或多个(一般是字节的整数位)字节构成。例如286微机的字由2个字节组成,它的字长为16;486微机的字由4个字节组成,它的字长为32位机。
计算机的字长决定了其CPU一次操作处理实际位数的多少,由此可见计算机的字长越大,其性能越优越。

二 编码

下载一个文档,一打开发现是乱码,不抓狂才怪…… 你们都知道,这都是字符编码闯的祸。ASCII、ANSI、GB18030、Unicode、UTF-8、UTF-8 with BOM、UTF without BOM、UTF-16、UTF-16LE、UTF-16BE…… 一大坨的谁分得清?听说UTF-8就是Unicode,但怎么Windows记事本里的保存选项有UTF-8和Unicode两个选项呀?!究竟各种软件是怎样判断一个文件是什么编码呢?为什么有时候又判断错误呢?让我一一道来。
世界上本没有字符编码。自从有了计算机,我们有了用0和1记录文字的需求,于是字符就有了编码。
== ASCII ==
ASCII编码表示的“Hello GuoKr”(十进制):72 101 108 111 32 71 117 111 75 114
ASCII是最基本的编码,它定义了0~127对应的字符,包括最基本的英文字母、标点符号。它无法表示中文。ASCII编码的文本,每一个字节都是0~127,如果某个字节大于127,那它一定不是ASCII编码。
== GB* / ANSI ==
为了用计算机记录并显示中文,中国人发明了GB系列编码。GB系列编码定义了中文汉字、标点的编码。按照GB系列编码,在一段文本中,如果一个字节是0~127,那么这个字节的含义同ASCII编码,否则,这个字节和下一个字节共同组成汉字(或是GB编码定义的其他字符)。因此,GB系列编码向下兼容ASCII,也就是说,如果一段用GB编码文本里的所有字符都在ASCII中有定义,那么这段编码和ASCII编码完全一样。GB编码早期收录的汉字不足一万个,基本满足日常使用需求,但不包含一些生僻的字,后来在一个个新版本中加进去。最早的GB编码是GB2312,后来有GBK,最新的是GB18030,加入了一些国内少数民族的文字,一些生僻字被编到4个字节,每扩展一次都完全保留之前版本的编码,所以每个新版本都向下兼容。
同样,日文、韩文、世界各国文字都有了它们各自的编码(如果ASCII不能满足使用要求的话)。这些编码都和GB编码相似,兼容ASCII并用两个字节表示一个字。所有这些各国文字编码,微软统称为ANSI 。所以即使知道是ANSI,我们还需要知道这是哪国文字才能解码,因为这些编码都互相冲突。另外,你无法用一段ANSI 编码表示既有汉字、又有韩字的文本。
等等,上面我误导大家了……其实是微软误导大家了,严格来说ANSI 不是字符编码,而是美国一个非营利组织,他们做了很多标准制定工作,包括C语言规范ANSI C,还有各国文字编码对应的“代码页”(code page)。ANSI 规定简体中文GB编码的代码页是936,所以GB编码又叫做ANSI code page 936(按ANSI标准的代码页936),各国编码被统称为ANSI 由来于此——这是个离谱的历史错误,这就像我自己给国内的大学做了个排名,排名的依据是饭堂吃出虫子的概率,然后国内的大学就被统称为黄油猫。不过对于这些乱七八糟互相冲突的多国字符编码,有个统称还是不错的(我了个去还要谢谢微软),下面讨论姑且继续使用ANSI 。
==Unicode / UTF / UCS==
为了解决冲突的问题,促进世界和平,我们有了Unicode(联合码?)——一种将全世界所有语言所有字符都收录在一起、让它们和平共处的编码……哦,等等,Unicode虽是一种字符编码,但严格来说它和GB18030不能相提并论:它只定义了每一个字符对应一个整数(目前包含了十万多个字符,其中0~127和ASCII完全一样),但它没有定义这个整数如何变成字节。当你告诉我这段数据是Unicode编码,啊,不好意思,我还是不知道该怎么解码——因为变成字节流的格式不只一种,它们都叫做“Unicode转换格式”(Unicode Transformation Format,简称为UTF)。
所以这里面就有了一大堆UTF:UTF-8、UTF-8 with BOM、UTF-8 without BOM、UTF-16、UTF-16LE、UTF-16BE…… 还有很少见的UTF-32、,早期还会听说过UCS-2、UCS-4…… (:з」∠)
等等,为什么Windows记事本里有个保存选项是Unicode?这个稍后说。
先说最常见的UTF-8:它将一个字符编为1-4个字节,其中一个字节的字符和ASCII 完全一致,所以它也向下兼容ASCII。和ANSI类似,UTF-8第一个字节决定了之后多少个字节是一组好基友。多数汉字在UTF-8里为3个字节,有一些生僻的汉字会编到4字节。
我们迎来第一种不兼容ASCII的编码:UTF-16。UTF-16以每2个字节为一个单元,每个字符由1-2个单元组成,所以每个字符可能是2个字节或者4个字节,包括最常见的英文字母都会编成两个字节。大部分汉字也是2个字节,少部分生僻字为4个字节。UTF-16还有讲究,一个单元中的两个字节的顺序不是唯一的。学过计算机原理的同学知道,计算机中表示一个整数分两种格式:低位在前高位在后,或者反过来。例如用两个字节表示260这个整数,可能是:
低位在前:04 01 (260=4+256*1)
高位在前:01 04 (260=256*1+4)
低位在前的UTF-16叫UTF-16LE,高位在前的叫UTF-16BE。目前绝大部分的计算机系统都使用低位在前的整数格式,所以如果没有声明,UTF-16默认是LE。
早期Unicode收编的字还不多时,两个字节足够表示所有字符,所以有一种固定为两个字节的UTF,叫UCS-2。UTF-16的两个字节部分和UCS-2完全一样,所以UTF-16向下兼容UCS-2。UCS-2同样分LE和BE。而Windows的记事本还有Windows其它地方所谓的Unicode,当代的Windows里其实是UTF-16LE,在Windows XP和更早的版本里是UCS-2LE。微软(又是微软)正是混淆Unicode概念的祸首,微软你这么讨厌你家人知道吗?
此外,UTF-32和UCS-4固定为4个字节一个字符,同样分LE和BE。
还没完,这么多字符编码,软件打开时如何知道是哪个编码?于是不知道谁蹲坑时想出了BOM:在一个文本文件或者一段字符编码前加上几个固定的字节用于识别,这些字节保证不对应任何一个字符,所以软件一读就能验明正身:
EF BB BF - 我是UTF-8
FF FE - 我是UTF-16LE
FE FF - 我是UTF-16BE
(没有BOM,直奔主题)-你猜?
不错,没BOM只能靠猜了。软件读入文件时可以所有编码都试一下,看哪个像。另外,BOM只针对Unicode系列编码,ANSI通通不会有BOM。很显然,没有BOM难免偶然猜错。网上就流传了一个神奇的段子:打开Windows记事本,打入“联通”两个字,保存,关闭,再打开,变成了个黑块。记事本用ANSI(GB18030)保存联通这两个字,刚好这两个字的GB18030编码看起来很像UTF-16,于是就当成UTF-16来打开……
BOM听起来很不错,但实际是个讨厌的设计,因为它和很多协议、规范不兼容,这是题外话。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值