字节、字符以及字符编码之间的关系

一、简介

可能很多人都有遇到过这样一个问题:“字符与字节有什么区别?”

其实,字符与字节它们完全是两个不同的的概念,所以两者之间也没有“区别”这一说法。通俗的来说,字节是一种储存数据的单位,而字符则是一些平常我们使用的文字符号(如字母、数字、标点符号)。

二、字节

字节(Byte)是计算机信息技术用于计量存储容量的一种计量单位,通常情况下一字节等于有八位,也就是二进制的0000000011111111,所以一个字节(Byte)可区别256(2的8次方)个数字(字符)。

单位换算规则:

8bit(位) = 1Byte
1024Byte = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
1024PB = 1EB
1024EB = 1ZB
1024ZB = 1YB
1024YB = 1BB
1024BB = 1NB
1024NB = 1DB

三、字符编码

这里先对几个概念做个简单的介绍:
字符——文字与符号的统称(如字母、数字、标点符号)
字符集——就是各种字符的集合
字符编码——就是为字符集中的每一个字符规定一串对应二进制数的一套规则(如在ASCII码中,大写的字母A是01000001)

字符编码(也称字集码)的种类有非常多,每个国家也会根据自己的文字类型来规定适用的字符编码。

常见的字符编码有:ASCII、 Unicode、UTF-8、GBK(简、繁体字融于一库)、GB2312(简体中文字符集)、Big5(繁体中文字符集)等。

1、ASCII 码

美国根据自己的26个字母,规定了一套共128个字符的编码,叫ASCII码。每个ASCII字符占用1 个字节,而一个字节能够表示256个字符,所以标准的ASCII码只使用了一个字节的后面7位,最前面的1位统一规定为0。

标准ASCII码包含了33个控制字符(具有某些特殊功能但是无法显示的字符)和95个可显示字符。

英语用128个符号编码就够了,但是用来表示其他语言,128个符号很多时候是不够的。所以有些国家就把ASCII码字节中闲置的最高位也编入新的符号,这样就可以表示最多256个符号了。我们把利用128--255这一段的叫做扩展ASCII码。

在 linux 系统中,也可以用如下命令查看ASCII表:

[nosee@instance-4 ~]$ ascii
Usage: ascii [-adxohv] [-t] [char-alias...]
   -t = one-line output  -a = vertical format
   -d = Decimal table  -o = octal table  -x = hex table  -b binary table
   -h = This help screen -v = version information
Prints all aliases of an ASCII character. Args may be chars, C \-escapes,
English names, ^-escapes, ASCII mnemonics, or numerics in decimal/octal/hex.

Dec Hex    Dec Hex    Dec Hex  Dec Hex  Dec Hex  Dec Hex   Dec Hex   Dec Hex  
  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p
  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q
  2 02 STX  18 12 DC2  34 22 "  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r
  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s
  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t
  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u
  6 06 ACK  22 16 SYN  38 26 &  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v
  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w
  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x
  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y
 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z
 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {
 12 0C FF   28 1C FS   44 2C ,  60 3C <  76 4C L  92 5C \  108 6C l  124 7C |
 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }
 14 0E SO   30 1E RS   46 2E .  62 3E >  78 4E N  94 5E ^  110 6E n  126 7E ~
 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL

2、Unicode 编码

正如前面所说,字符编码的种类有非常多,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字所表示的,这是一种所有符号的编码,由国际组织设计。所以 Unicode 是一个很大的集合,现在的规模可以容纳100多万个符号,每个符号的编码都不一样。

需要注意的是,Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。比如,汉字的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

所以就会出现两个严重的问题:第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:1)出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。2)Unicode 在很长一段时间内无法推广,直到互联网的出现。

常见Unicode编码范围:
-- 汉字:[0x4e00,0x9fa5](或十进制[19968,40869])
-- 数字:[0x30,0x39](或十进制[48, 57])
-- 小写字母:[0x61,0x7a](或十进制[97, 122])
-- 大写字母:[0x41,0x5a](或十进制[65, 90])

3、UTF-8编码

UTF-8 就是在互联网上使用最广的一种字符编码,是 Unicode 的实现方式之一。UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

如:在UTF-8编码中,一个英文字符占一个字节,一个中文(含繁体)占三个字节;中文标点占三个字节,英文标点占一个字节。

UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码(因此对于英语字母,UTF-8 编码和 ASCII 码是一样的)
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

下表总结了编码规则,字母x表示可用编码的位:

Unicode符号范围      |      UTF-8编码方式
   (十六进制)        |        (二进制)
--------------------+-----------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

下面,还是以汉字为例,演示如何实现 UTF-8 编码:
的 Unicode 是4E25100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从的最后一个二进制位开始,依次从后向前把(100111000100101)填入格式中的x,多出的x位补为0。这样就得到了,严的 UTF-8 编码:11100100 10111000 10100101,转换成十六进制就是E4B8A5

从上一小节我们看到了中文在Unicode编码的范围为[0x4e00,0x9fa5],然后对应上面的对照表可以看出,这个范围都是处在第三行的,所以可以说“一个中文字符在UTF-8编码中占用了3个字节”。

UTF8 和 UTF8+BOM 问题:
什么是BOM? BOM(byte of mark)是一个 Unicode 中一个特殊字符;表示0长度,非断行的空格。
BOM出现的初衷:BOM最初是用来区分UTF-16和UTF-32的;UTF-16编码使用内容“FE FF”的BOM来标记big ending,即高位结束符;用“FF EE”标记 small ending,即低位结束符。
微软记事本带来的麻烦:在 UTF-8 文件中放置 BOM 主要是微软的习惯,Windows的记事本有个臭名昭著的破毛病就是在 UTF-8 文件开头加 BOM,在不支持或者未识别utf8编码的环境下,该BOM会被解析成乱码“"”,导致问题。

其它相关类型:UTF-16(字符用两个字节或四个字节表示)、UTF-32(字符用四个字节表示)

四、参考

在线工具:Unicode 字符百科
什么是Unicode(编码标准)?
阮一峰的网络日志:ASCII,Unicode 和 UTF-8
https://home.unicode.org
字体编辑用中日韩汉字Unicode编码表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容