- UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 因此UTF-8中可以用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去那些控制位(每字节开头的10等),这些x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。 实际将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数。 因此那些基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一个字节的UTF-8编码(7个二进制位)便可以表示。
如下:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -
编码单位
最小的单元是位(bit),接着是 字节(Byte),一个字节=8位,英语表示是1 byte=8 bits 。 机器语言的单位Byte。1 KB=1024 Byte; 1 MB=1024 KB; 1 GB=1024 MB ; 1TB=1024 GB。进制
二进制数由0和1,八进制数由0-7, 十进制数由0-9,十六进制数由0-9,A,B,C,D,E,F组成,他们关系如下:Binary(2)Octal(8)Decimal(10)Hex(16)0000011111022211333100444101555110666111777100010881001119910101210A10111311B11001412C11011513D11101614E11111715F上层字符
字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。 字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB 18030字符集、Unicode 字符集等。计算机要准确的处理各种 字符集文字,需要进行 字符编码,以便计算机能够识别和存储各种文字。编辑本段编码分类
1.ASCIIASCII(American Standard Code for Information Interchange, 美国信息互换标准代码)是基于 罗马字母表的一套电脑编码系统,它主要用于显示现代英语和其他 西欧语言。它是现今最通用的单 字节编码系统,并等同于国际标准ISO 646。包含内容:可显示 字符:英文大小写字符、阿拉伯数字和西文符号ASCII扩展 字符集扩展:表格符号、计算符号、希腊字母和特殊的拉丁符号。第0~31号及第127号(共33个)是 控制字符或通讯专用字符,如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BEL(振铃)等;通讯专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;第32~126号(共94个)是 字符,其中第48~57号为0~9十个阿拉伯数字;65~90号为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。 注意:在计算机的 存储单元中,一个ASCII码值占一个 字节(8个二进制位),其最高位(b7)用作 奇偶校验位。所谓 奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分 奇校验和偶校验两种。 奇校验规定:正确的代码一个 字节中1的个数必须是奇数,若非奇数,则在最高位b7添1; 偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。八进制十六进制十进制字符八进制十六进制十进制字符000nul1004064@111soh1014165A222stx1024266B333etx1034367C444eot1044468D555enq1054569E666ack1064670F777bel1074771G1088bs1104872H1199ht1114973I120a10nl1124a74J130b11vt1134b75K140c12ff1144c76L150d13er1154d77M160e14so1164e78N170f15si1174f79O201016dle1205080P211117dc11215181Q221218dc21225282R231319dc31235383S241420dc41245484T251521nak1255585U261622syn1265686V271723etb1275787W301824can1305888X311925em1315989Y321a26sub1325a90Z331b27esc1335b91[341c28fs1345c92\351d29gs1355d93]361e30re1365e94^371f31us1375f95_402032sp1406096'412133!1416197a422234"1426298b432335#1436399c442436$14464100d452537%14565101e462638&14666102f472739`14767103g502840(15068104h512941)15169105i522a42*1526a106j532b43+1536b107k542c44,1546c108l552d45-1556d109m562e46.1566e110n572f47/1576f111o603048016070112p613149116171113q623250216272114r633351316373115s643452416474116t653553516575117u663654616676118v673755716777119w703856817078120x713957917179121y723a58:1727a122z733b59;1737b123{743c60<1747c124|753d61=1757d125}763e62>1767e126~773f63?1777f127del2.GB2312GB2312又称为 GB2312-80 字符集,全称为《信息交换用汉字编码字符集·基本集》,由原 中国国家标准总局发布,1981年5月1日实施,是中国国家标准的简体中文字符集。它所收录的汉字已经覆盖99.75%的使用频率,基本满足了汉字的计算机处理需要。在 中国大陆和 新加坡获广泛使用。GB2312收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共 7445 个图形 字符。其中包括6763个汉字,其中一级汉字3755个,二级汉字3008个;包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语 西里尔字母在内的682个 全角字符。GB2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。它是用双 字节表示的,两个字节中前面的字节为第一字节,后面的字节为第二字节。习惯上称第一 字节为“高字节” ,而称第二字节为“低字节”。“高位 字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上0xA0)。以GB2312 字符集的第一个汉字“啊”字为例,它的区号16,位号01,则区位码是1601,在大多数计算机程序中,高 字节和低字节分别加0xA0得到程序的汉字处理编码0xB0A1。计算公式是:0xB0=0xA0+16, 0xA1=0xA0+1。3.GBK4. BIG5BIG5又称 大五码或五大码,1984年由 台湾财团法人 信息工业策进会和五间 软件公司宏碁 (Acer)、神通 (MiTAC)、佳佳、零壹 (Zero One)、大众 (FIC)创立,故称大五码。Big5码的产生,是因为当时 台湾不同厂商各自推出不同的编码,如倚天码、IBM PS55、 王安码等,彼此不能兼容;另一 方面, 台湾政府当时尚未推出官方的 汉字编码,而 中国大陆的GB2312编码亦未有收录繁体中文字。Big5码使用了双 字节储存方法,以两个字节来编码一个字。第一个 字节称为“高位字节”,第二个字节称为“低位字节”。 高位 字节的编码范围0xA1-0xF9,低位字节的编码范围0x40-0x7E及0xA1-0xFE。尽管Big5码内包含一万多个 字符,但是没有考虑社会上流通的人名、地名用字、方言用字、化学及生物科等用字,没有包含日文平假名及片假字母。例如 台湾视“着”为“著”的异体字,故没有收录“着”字。康熙字典中的一些部首用字(如“亠”、“疒”、“辵”、“癶”等)、常见的人名用字(如“堃”、“煊”、“栢”、“喆”等) 也没有收录到Big5之中。5. GB18030GB18030的全称是GB18030-2000《信息交换用 汉字编码 字符集基本集的扩充》,是我国政府于2000年3月17日发布的新的汉字编码国家标准,2001年8月31日后在 中国市场上发布的 软件必须符合本标准。GB 18030 字符集标准的出台经过广泛参与和论证,来自国内外知名 信息技术行业的公司,信息产业部和原国家质量技术监督局联合实施。GB 18030 字符集标准解决汉字、日文假名、朝鲜语和 中国少数民族文字组成的大字符集计算机编码问题。该标准的 字符总编码空间超过150万个编码位,收录了27484个汉字,覆盖中文、日文、朝鲜语和 中国少数民族文字。满足 中国大陆、 香港、 台湾、 日本和 韩国等 东亚地区信息交换多文种、大字量、多用途、统一编码格式的要求。并且与Unicode 3.0版本兼容,填补Unicode扩展 字符字汇“统一汉字扩展A”的内容。并且与以前的国家 字符编码标准(GB2312,GB13000.1)兼容。编码方法:GB 18030标准采用单 字节、双 字节和四字节三种方式对 字符编码。单 字节部分使用0×00至0×7F码(对应于ASCII码的相应码)。双 字节部分,首字节码从0×81至0×FE,尾字节码位分别是0×40至0×7E和0×80至0×FE。四 字节部分采用GB/T 11383未采用的0×30到0×39作为对双字节编码扩充的后缀,这样扩充的四字节编码,其范围为0×81308130到0×FE39FE39。其中第一、三个 字节编码码位均为0×81至0×FE,第二、四个字节编码码位均为0×30至0×39。接着是国际通用的unicode 字符集6.ANSI编码不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个 字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文 操作系统下,ANSI 编码代表 JIS 编码。7.Unicode1.名称的由来Unicode 字符集编码是(Universal Multiple-Octet Coded Character Set) 通用多八位编码字符集的简称,支持世界上超过650种语言的国际字符集。Unicode允许在同一服务器上混合使用不同语言组的不同语言。它是由一个名为 Unicode 学术学会(Unicode Consortium)的机构制订的 字符编码系统,支持现今世界各种不同语言的书面文本的交换、处理及显示。该编码于1990年开始研发,1994年正式公布,最新版本是2005年3月31日的Unicode 4.1.0。Unicode是一种在计算机上使用的 字符编码。它为每种语言中的每个 字符设定了统一并且唯一的 二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。2.编码方法Unicode 标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”,例如字母“A”的编码为 004116 。所以“A”的编码书写为“U+0041”。3.UTF-8 编码UTF-8是Unicode的其中一个使用方式。 UTF是 Unicode Translation Format,即把Unicode转做某种格式的意思。UTF-8使用可变长度 字节来储存 Unicode 字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或 西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。 辅助平面 字符则使用4 字节。4.UTF-16 和 UTF-32 编码UTF-32、 UTF-16和 UTF-8 是 Unicode 标准的编码 字符集的 字符编码方案,UTF-16 使用一个或两个未分配的 16 位代码单元的序列对 Unicode 代码点进行编码;UTF-32 即将每一个 Unicode 代码点表示为相同值的 32 位整数通过一个问题了解unicode编码问题:使用Windows 记事本的“ 另存为”,可以在ANSI、GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows怎样识别编码方式的呢?我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个 字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?答案:ANSI字符集定义:ASCII字符集,以及由此派生并兼容的字符集,如:GB2312,正式的名称为MBCS(Multi-Byte Chactacter System,多字节字符系统),通常也称为ANSI字符集。UNICODE 与 UTF8、UTF16由于每种语言都制定了自己的 字符集,导致最后存在的各种字符集实在太多,在国际交流中要经常转换字符集非常不便。因此,产生了Unicode 字符集,它固定使用16 bits(两个 字节)来表示一个字符,共可以表示65536个字符标准的 Unicode 称为UTF-16(UTF:UCS Transformation Format )。后来为了双 字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8,使用类似MBCS的方式对Unicode进行编码。(Unicode 字符集有多种编码形式)例如"连通"两个字的Unicode标准编码UTF-16 (big endian)为:DE 8F 1A 90而其UTF-8编码为:E8 BF 9E E9 80 9A检测 文件头标识,提示用户选择,根据一定的规则猜测最标准的途径是检测文本最开头的几个 字节,开头字节 Charset/encoding,如下表:EF BB BF : UTF-8FF FE : UTF-16/UCS-2, little endianFE FF : UTF-16/UCS-2, big endianFF FE 00 00 : UTF-32/UCS-4, little endian.00 00 FE FF : UTF-32/UCS-4, big-endian.1、big endian和little endianbig endian和little endian是CPU处理多 字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。“endian”这个词出自《 格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头( Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。我们一般将endian翻译成“ 字节序”,将big endian和little endian称作“大尾”和“小尾”。GB2312(1980年)一共收录了7445个 字符,包括6763个汉字和682个其它符号。汉字区的 内码范围高 字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。PC平台必须支持GB18030,对 嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个 字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高 字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。有的中文Windows的缺省 内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的 字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows 内码。这里还有一些细节:在DBCS中,GB 内码的存储格式始终是big endian,即高位在前。GB2312的两个 字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低 字节最高位都可能不是1。不过这不影响DBCS 字符流的解析:在读取DBCS字符流时,只要遇到高位为1的 字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。3、Unicode、UCS和UTF(UCS Transformation Format)前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。UCS规定了怎么用多个 字节表示各种文字。而怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的!常见的UTF规范包括UTF-8、UTF-7、UTF-16。4、UTF的字节序和BOMUTF-8以 字节为编码单元,没有 字节序的问题。UTF-16以两个 字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的 字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16 字节流“594E”,那么这是“奎”还是“乙”?Unicode规范中推荐的标记 字节顺序的方法是BOM。BOM不是“Bill Of Material”的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编码了。Windows就是使用BOM来标记文本文件的编码方式的。写到这里对编码有了大致的了解了,就可以理解网上一些文章的话了,比如有一篇很流行的文章《URL编码与SQL注射》里面有一段是这么说的:其实url编码就是一个字符 ascii码的十六进制。不过稍微有些变动,需要在前面加上“%”。比如“\”,它的ascii码是92,92的十六进制是5c,所以“\”的url编码就是%5c。那么汉字的url编码呢?很简单,看例子:“胡”的ascii码是-17670,十六进制是BAFA,url编码是“%BA%FA”。呵呵,知道怎么转换的了吧。这得从ASCII说起,扩展的ASCII 字符集采用8bit255个字符显然不够用,于是各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做“GB2312-80”(就是GB2312),它是和ASCII兼容的一种编码规范,其实就是用 扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示。文中说的的中文ASCII码实际上就是简体中文的编码2312GB!它把ASCII又扩充了一个 字节,由于高位的第一位是0,所以会出现负数的形式,url编码就是将汉字的这个GB2312编码转化成UTF-8的编码并且每8位即一个 字节前面加上%符号表示。那为何UTF-8是进行网络的规范传输编码呢?在Unicode里,所有的 字符被一视同仁。汉字不再使用“两个扩展ASCII”,而是使用“1个Unicode”,注意,汉字是“一个字符”了,于是,拆字、统计字数这些问题也就自然而然的解决了。但是,这个世界不是理想的,不可能在一夜之间所有的系统都使用Unicode来处理 字符,所以Unicode在诞生之日,就必须考虑一个严峻的问题:和ASCII 字符集之间的不兼容问题。我们知道,ASCII 字符是单个 字节的,比如“A”的ASCII是65。而Unicode是双 字节的,比如“A”的Unicode是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了另一个更加严重的问题是,C语言使用’\0’作为 字符串结尾,而Unicode里恰恰有很多字符都有一个 字节为0,这样一来,C语言的 字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所用的函数库全部换掉于是,比Unicode更伟大的东东诞生了,之所以说它更伟大是因为它让Unicode不再存在于纸上,而是真实的存在于我们大家的电脑中。那就是:UTFUTF= UCS Transformation Format UCS转换格式,它是将Unicode编码规则和计算机的实际编码对应起来的一个规则。现在流行的UTF有2种:UTF-8和UTF-16其中UTF-16和上面提到的Unicode本身的编码规范是一致的,这里不多说了。而UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容,这样做的好处是压缩了 字符在 西欧一些国家的内存消耗,减少了不必要的资源浪费,这在实际应用中是非常有必要的。UTF-8有点类似于Haffman编码,它将Unicode编码为:80-7FF的 字符用两个字节表示 (中文的编码范围)800-FFFF的字符用3 字节表示看看编码之多:ANSI,AscII,GB2312,GBK,BIG5,GB18030,Unicode,UCS(就是unicode)Utf-8, utf-16,utf-32 整整10种编码~,算是够复杂了可是这还仅仅是个开始,应用方面变化无穷。哦,漏了一个加密的base64编码。什么是Base64?按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位 字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)为什么要使用Base64?在设计这个编码的时候,我想设计人员最主要考虑了3个问题:1.是否加密?2. 加密算法复杂程度和效率3.如何处理传输?加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。这种加密方式主要就是“防君子不防小人”。即达到一眼望去完全看不出内容即可。基于这个目的加密算法的复杂程度和效率也就不能太 大和太低。和上一个理由类似,MIME协议等用于发送Email的协议解决的是如何收发Email,而并不是如何安全的收发Email。因此算法的复杂程度要小,效率要高,否则因为发送Email而大量占用资源,路就有点走歪了。但是,如果是基于以上两点,那么我们使用最简单的 恺撒法即可,为什么Base64看起来要比恺撒法复杂呢?这是因为在Email的传送过程中,由于历史原因,Email只被允许传送ASCII 字符,即一个8位 字节的低7位。因此,如果您发送了一封带有非ASCII 字符(即 字节的最高位是1)的Email通过有“历史问题”的 网关时就可能会出现问题。 网关可能会把最高位置为0!很明显,问题就这样产生了!因此,为了能够正常的传送Email,这个问题就必须考虑!所以,单单靠改变字母的位置的恺撒之类的方案也就不行了。关于这一点可以参考RFC2046。基于以上的一些主要原因产生了Base64编码。
编码规范
最新推荐文章于 2022-09-29 20:43:46 发布