您的位置:首页 > 理论基础

编码 区别 由来

2017-09-09 10:28 225 查看
10进制,2进制,8进制,16进制 基础

2进制就是每一位用0,1表示;

8进制就是每一位用0,1,2,3,4,5,6,7表示;

16进制就是每一位用0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F表示

字符和字节的区别

1个字节等于8个bit位,每个bit位又0/1两种状态也就是说一个字节可以表示256个状态,计算机里用字节来作为最基本的存储单位。一般来说,英文状态下一个字母或数字(称之为字符)占用一个字节,一个汉字用两个字节表示。(只是在ASCII下这样,Unicode不是)

ANSI,ASCII,Unicode,GB-2312,UCS-2,UTF-8关系

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为“字节”

再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去。他们看到这样是好的,于是它们就把这机器称为“计算机”。

开始计算机只是在美国使用。八位的字节一共可以组合出256(2的8次方)种不同的状态。(最早的ASCII)

他们把其中编号从0开始到31的32种状态分别规定了特殊的用途,一但终端、打印机遇到了这些被传过来的字节时,就要做一些约定的动作。遇上0x10,终端就换行,遇上0x07, 终端就向人们嘟嘟叫,遇上0x1B, 打印机就打印反白的字,或者终端将使用用彩色显示字母。他们看到这样很好,于是就把这些编号0x20以下的状态称为“控制码”,这些编号称为字符编码。这样就出现了编码!

ANSI 和 ASCII联系就是:ASCII标准是ANSI这个组织制定的!

ASCII ,GB2312 ,Unicode 来由:

而ASCII是最早美国ANSI组织制定的编码,用了256位的127位表示英文字母和一些符号,但是很多国家并不使用英文,有许多文字是ASCII无法表示的,为了可以让计算机保存这些的文字,他们决定采用ASCII编码里第127号之后的空位来表示这些新的字母和符号,还加入了很多画表格时需要用到的横线、竖线、交叉等图形符号,一直把序号编到了八位字节可以表示的最后一个数字255。从128到255这一区域的字符集被称“扩展字符集”。但是随着中国强大,中文只就需要加入到计算机里,所以中国自己编制了GB2312(后来到最高级的GBK18030)编码,把128后到255位的拿来用了。又因为汉字就有6000多个,所以根本不够用,于是,我们把那些编码在127之后的奇异符号(扩展字符集)直接取消掉,并做出规定:一个编码小于127的字符与原来ASCII表示的意义相同,但当两个编码大于127的字符连在一起时,就表示一个汉字,前面的一个字节(高字节)取值0xA1~0xF7,后面一个字节(低字节)取值0xA1~0xFE,这样用两个字节就可以组合出大约7000多个简体汉字了。也就是两个字节表示一个汉字了。后来,干脆把127前的也改成两个字节表示,这就是“全角”了。相对的,原来编码在127以下的那些只用一个字节表示的字符就叫“半角”字符了。

但是,这样全球太多国家,太多语言了,每个国家都编一套,不现实!于是ISO(国际标谁化组织)来了。用Unicode编码来统一全球,但是如果还用8位一个字节这样不够用,于是,Unicode直接用2个字节代表一个字符,也就是16位!对于ASCII里的那些“半角”字符,UniCode保持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他国家的语言文字则全部重新统一编码。由于“半角”英文符号只需要用到低8位,所以其高8位永远是0,因此这种大气的方案在保存英文文本时会多浪费一倍的存储空间。

UCS-2,USC-4

Unicode是为整合全世界的所有语言文字而诞生的。任何文字在Unicode中都对应一个值,这个值称为代码点(code point)。代码点的值通常写成 U+ABCD 的格式。而文字和代码点之间的对应关系就是UCS-2(Universal Character Set coded in 2 octets)。顾名思义,UCS-2是用两个字节来表示代码点,其取值范围为 U+0000~U+FFFF。USC-4就是用四个字节表示代码点,怕以后不够用,才增加到4位,现在是两个字节

为何每个Unicode字符 写成 U+ABCD 的格式呢? 因为U就是Unicode编码,而ABCD是这样的,因为Unicode是用两个字节,也就是16位(一个字节8位)来表示一个字符,那么就等于可以有2的16次方=65536个不同字符(因为计算机只有0,1也就是开头所表达的希望用开,关两种状态表示地球上的东西,所为每个位只有0和1)。也就是Unicode可以表示65536种字符,而写成ABCD是用四个16进制的数字来表示,因为16的4次方=65536,那么就等于改为16进制表示。

要注意,UCS-2和UCS-4只规定了代码点和文字之间的对应关系,并没有规定代码点在计算机中如何存储。

UTF-16,UTF-32,UTF-8

规定存储方式的称为UTF(Unicode Transformation Format),其中应用较多的就是UTF-16和UTF-8了。UTF也是网络传输编码的方式。

不难猜到,UTF-16是完全对应于UCS-2的,即把UCS-2规定的代码点通过Big Endian或Little Endian方式直接保存下来。UTF-16包括三种:UTF-16,UTF-16BE(Big Endian),UTF-16LE(Little Endian)。

UTF-16BE和UTF-16LE不难理解,而UTF-16就需要通过在文件开头以名为BOM(Byte Order Mark)的字符来表明文件是Big Endian(高字位)还是Little Endian(低字位)。BOM为U+FEFF这个字符。 其实BOM是个小聪明的想法。由于UCS-2没有定义U+FFFE,因此只要出现 FF FE 或者 FE FF 这样的字节序列,就可以认为它是U+FEFF,并且可以判断出是Big Endian还是Little Endian。

举个例子:

“ABC”这三个字符用各种方式编码后的结果如下:

UTF-16BE 00 41 00 42 00 43

UTF-16LE 41 00 42 00 43 00

UTF-16(Big Endian) FE FF 00 41 00 42 00 43

UTF-16(Little Endian) FF FE 41 00 42 00 43 00

UTF-16(不带BOM) 00 41 00 42 00 43

Windows平台下默认的Unicode编码为Little Endian的UTF-16(即上述的 FF FE 41 00 42 00 43 00)。你可以打开记事本,写上ABC,然后保存,再用二进制编辑器看看它的编码结果。

UTF-16和UTF-32的一个缺点就是它们固定使用两个或四个字节,这样在表示纯ASCII文件时会有很多00字节,造成浪费。而RFC3629定义的UTF-8则解决了这个问题。

顾名思义,那个8说明UTF-8编码中最小的单位是8bit的一个字节。采用UTF-8编码,Unicode代码点中U+007F以下(包含U+007F)的字符用一个字节编码,其它的字符用多个字节编码,最多一个字符用4(真正是6个)个字节编码。这样UTF-8兼容ASCII,但是不兼容ISO-Latin字符集。(UTF—8 是指最小单位是一个字节,8bit) Unicode字符采用UTF-8编码方案时的对照表: U-00000000 - U-0000007F: 0xxxxxxx (一个字节)

U-00000080 - U-000007FF: 110xxxxx 10xxxxxx (两个字节)

U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx (三个字节)

U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (五个字节)

U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (六个字节)

这里已经表示超过65536个元素 网上的很多文章都有这个表,可以看到一个Unicode代码点采用UTF-8编码时最多可达6个字节。但是从Unicode官方网站上看到的
4000
是UTF-8编码的最大字节长度是4个字节。也就是说最下面的两行没有了。4个字节 意见超过表示65536个元素了,因为4个字节最大表示U-001FFFFF 这里就有1FFFFF 6个数,也就是16的6次方个元素了 。

例子:UTF-8编码的实现方式比较好理解。

例如“汉”字的Unicode编码是6C49,6C49在0800-FFFF之间,(大家都是16位编码) 所以最终编码应该是3个字节。6C49的二进制位串是:110110001001001,把这个位串从右向左(从后往前)填充到那3个字节的x部分,高位不够的用0补。

(U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx) 最终得到的3个字节是:11100110 10110001 10001001,即E6 B1 89。注意由于UTF-8的最小编码单元是字节,而UTF-16和UTF-32最少编码单元是位(bit)。重要是UTF-8不同范围的字节数不同的,不像UTF-16这样规定用两个字节,就不会出现例如:“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?所以不存在大端小端(高字位,低字位)的问题。

一般一个16位(双字节)的数据,比如 OXFF1A (16进制) 那么高位字就是FF,低位是1A 如果是32位的数据,比如 3F68415B 高位字(不是字节)是3F68 低位字是415B 右边是低位位,左边是高位。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编码 计算机 存储