admin 管理员组

文章数量: 887031


2024年1月4日发(作者:nginx createfile)

附录B常用字符集编码概要

常用字符集编码概要特性

 ASCII

ASCII码是7位编码,编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。只支持ASCII码的系统会忽略每个字节的最高位,只认为低7位是有效位。HZ字符编码就是早期为了在只支持7位ASCII系统中传输中文而设计的编码。早期很多邮件系统也只支持ASCII编码,为了传输中文邮件必须使用BASE64或者其他编码方式。

 ISO-8859-1

ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。ISO-8859-1收录的字符除ASCII收录的字符外,还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。欧元符号出现的比较晚,没有被收录在ISO-8859-1当中。因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性。ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。

 GB2312-80

GB2312是基于区位码设计的,区位码把编码表分为94个区,每个区对应94个位,每个字符的区号和位号组合起来就是该汉字的区位码。区位码中01-09区是符号、数字区,16-87区是汉字区,10-15和88-94是未定义的空白区。GB2312字符集中除常用简体汉字字符外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符,未收录繁体中文汉字和一些生僻字。可以用繁体汉字测试某些系统是不是只支持GB2312编码。

GB2312-80(1980年)是国内计算机汉字信息技术发展初始阶段制定的,其中包含了大部分常用的一、二级汉字,和 9 区的符号。一共收录了7445个字符,包括6763个汉字和682个其它符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是 0xa1-0xfe;汉字从 0xb0a1 开始,结束于 0xf7fe。

 GBK

GBK编码是GB2312编码的超集,向下完全兼容GB2312,同时GBK收录了Unicode基本多文种平面中的所有CJK汉字。同 GB2312一样,GBK也支持希腊字母、日文假名字母、俄语字母等字符,但不支持韩语中的表音字符(非汉字字符)。GBK还收录了GB2312不包含的 汉字部首符号、竖排标点符号等字符。

GBK的整体编码范围是为0x8140-0xFEFE,不包括低字节是0×7F的组合。高字节范围是0×81-0xFE,低字节范围是0x40-7E和0x80-0xFE。

GBK所有字符都可以一对一映射到 Unicode 2.0,也就是说 JAVA 实际上提供了 GBK 字符集的支持。这是现阶段 Windows 和其它一些中文操作系统的缺省字符集,但并不是所有的国际化软件都支持该字符集。

中文Windows默认采用的是GBK编码显示,每个汉字对应两个字节,区分中文编码的方法是高字节的最高位不为0(符号位,1负数;0正数)。

 GB18030-2000(GBK2K)

(2000年)在 GBK 的基础上进一步扩展了汉字,增加了藏、蒙等少数民族的字形。该标准收录了27484个汉字,GBK2K 从根本上解决了字位不够,字形不足的问题。

GBK和GB2312是单字节和双字节混合的变长编码,英文1位,中文2位。GB18030编码是变长编码,有单字节、双字节和四字节三种方式

 UCS

UNICODE编码(Universal Multiple-Octet Coded Character Set",简称为UCS),兼容英文字符和其它民族的字符编码,所以,目前,大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。

UCS-2、UTF-16是UCS字符集(或者说是Unicode字符集)实际应用中的具体编码方式。

 UTF-8,UTF-16,UTF-32

Unicode的最初目标,是用1个16位的编码来为超过65000字符提供映射。但这还不够,它不能覆盖全部历史上的文字,也不能解决传输的问题,尤其在那些基于网络的应用中。因此,Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。

UTF-8是8 位 UCS 转换格式,编码是字节顺序无关的,变长码。UTF-8是UNICODE的一种变长字符编码, UTF-8用1到6个字节编码UNICODE字符。如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。这种方式的最大好处,是UTF-8保留了ASCII字符的编码做为它的一部分,例如,在UTF-8和ASCII中,“A”的编码都是0x41,其缺点长度不可知,物理存储有问题。

UTF-16和UTF-32分别是Unicode的16位和32位编码方式。通常说的Unicode就是指UTF-16。UTF-16BE是16 位 UCS 转换格式,Big Endian(最低地址存放高位字节)字节顺序。

UTF-16LE是16 位 UCS 转换格式,Little-endian(最高地址存放低位字节)字节顺序。

UTF-16是16 位 UCS 转换格式,字节顺序由可选的字节顺序标记来标识,定长码。

UCS-2用2个字节来编码字符,两个字节就是16位二进制,2的16次方等于65536,所以UCS-2最多能编码65536个字符。

UCS-4用4个字节来编码字符。

 BIG5

BIG5是台湾计算机界实行的汉字编码字符集。它包含了 420 个图形符号和 13070 个汉字(不包含简化汉字)。编码范围是 0x8140-0xFE7E、0x81A1-0xFEFE,其中 0xA140-0xA17E、0xA1A1-0xA1FE 是图形符号区,0xA440-0xF97E、0xA4A1-0xF9FE 是汉字区。

 编码示例

字符

US-ASCII

ISO8859-1

GBK

BIG5

UTF-16BE

UTF-16LE

UTF-8

“A”

41

41

41

41

0041

4100

41

“国” “國”

3f(错误) 3f

3f 3f

b9 fa 87 f8

3f(错误) b0 ea

56 fd 57 0b

fd 56 0b 57

e5 9b bd e5 9c 8b

短信相关

 GSM短信长度为140个8位组(字节)。

 对于UCS-2或UTF-16,每个字符为2个字节,故最长可传输70个UCS2字符(如中文)

 对于Alphabet编码(英文即以此方式传输),每个字符为7bits,因此可传输160个字符

 看下图的表示:

英文(半角)(byte数组)

1 2 3 4 5 …… 160

0 7 6 5 4 3 2 1

(每个字节7bits表示,最高位恒为0)

中文(byte数组)

1 2 3 4 5 …… 140

(2×70)

8 7 6 5 4 3 2 1

(一个字节8bits表示)

(70×2×8=160×7)

 所以如果全部是半角英文的话,使用Alphabet编码最多可传160个字符;如果是中文,使用UCS-2或UTF-16最多可传70个汉字。

短信传输一般用UTF-16BE。在GBK编码中有简体的国和繁体的國编码。但这2个字的编码是不一样

的。实际上表示的是同一个语意字,但是在GBK内一般情况下无法作转换。JVM内部数据传递时采用Unicode的编码,GBK,BIG5与Unicode有对应关系,但BIG5中部分简体中文字没有对应关系,这就造成了发往某些地区手机上显示的简体中文字可能是乱码。

Hex编码 Base64编码 QuotedPrintableCodec编码 URLcode编码

 Hex编码

Hex编码提供了字节数据到十六进制的编码和解码,就是执行字节数据和等价的十六进制表示形式之间的转换。十六进制用0-9,A-F共16个字符表示。Hex编码的优点是编码简单,缺点是长度是原来的2倍。

Hex编码示例,如字符“a”的byte值为97 ,经Hex编码得char 数组转换成字符串为“61”。

 Base64

Base64提供了基于RFC 2045(多用途互联网邮件扩充协议)。一共由0-9,a-z,A-Z,+/64各字符组成,用=补位。Base64编码主要用于Email传输,还用于BASIC认证机制中HTTP 认证头的"用户:密码"字符串。网上传输的二进制是8位一字节,而ASCII是7位为一字节。如果直接把二进制作为ASCII来显示会损失。Base64使得任何二进制数据都可以转换成可打印的ASCII字符集安全地传输。

BASE64编码规则。三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24)然后把6Bit再添两位高位0,组成四个8Bit的字节,编码后的字符串大小是原来的1.3倍。特点是:1、速度非常快。2、能够将字符串A转换成字符串B,看字符串B,猜不出字符串A的内容

Base64编码示例,如字符“a”的byte值为97 ,经Base64编码得到的char 数组转换成字符串为“YQ==”。

 URLCodec

URLCode对字符串进行编码时,使用以下规则:

1.)字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。

2.)特殊字符 "."、"-"、"*" 和 "_" 保持不变。

3.)空格字符 " " 转换为一个加号 "+"。

4.)所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。然后每个字节用一个包含 3 个字符的字符串 "%xy" 表示,其中 xy 为该字节的两位十六进制表示形式。推荐的编码机制是 UTF-8。但是,出于兼容性考虑,如果未指定一种编码,则使用相应平台的默认编码。

例如,使用 UTF-8 编码机制,字符串 "The string ü@foo-bar" 将转换为

"The+string+%C3%BC%40foo-bar",因为在 UTF-8 中,字符 ü 编码为两个字节C3 BC,字符 @ 编码为一个字节 40 (十六进制)。

 QuotedPrintableCodec

提供了基于RFC1521(多用途互联网邮件扩充协议)的编码和解码。

编码规则要求每个编码行的长度不超过76字节。如果需要编码更长的行,就必须要使用“软”换行符。在编码内容中,出现在一行最后位置的等号(“=”)表示无意义的换行符(软换行符)。(普通的8位字节描述)除了被编码内容中标准换行符CRLF序列里的CR和LF字节之外的任何字节,都应该被表示成“=”后面紧跟着两个表示字节值的十六进制数字的形式。此处使用的十六进制字符表是“ABCDEF”。必须使用大写字母,而不允许使用小写字母。因此,十进制的值12可以被表示为:“=0C”,十进制值61(表示US-ASCII字符集中的等号)可以被表示为“=3D”。

宽字符

在ANSI/ISO 9899--1990也就是美国国家为程序设计语言C指定的标准(也称为ANSI C)中是这样定义的:

用多个字节来代表的字符称之为宽字符,而Unicode只是宽字符编码的一种实现,宽字符并不一定是Unicode。

在Windows 1.0(1985年11月发布)中,微软发布windows自有的字符集称为ANSI字符集,因为它是基于ANSI和ISO标准的一个草案,而此草案最终称为ANSI/ISO 8859-1--1987,这也简称为"拉丁语-1"。

在MS-DOS 3.3中把代码页的概念介绍给了IBM-PC的用户。这一概念也转接到Windows操作系统中。代码页定义了字符的响应字符码。原本的IBM字符集被称为第437页代码页,第850页是MS-DOS Latin 1.但是代码页的数量超乎清理地的剧增。

这里面存在的一个基本问题是世界上的书面语言文字根本无法用256个8位代码来表示。以前的那些涉及代码页和DBCS编码已经被证明是不足和笨拙的。那儿Unicode编码也应运而生。

UNICODE字符称为宽字符(特别是在C编程环境里),每一个Unicode字符时16位宽而不是8位,C语言用unsigned short表示,可以存放世界上所有书面语言的所有字符和象形文字,还包括一批数学符号和装饰标志的集合。Unicode最棒的一个地方是它只有一个字符集,这就避免了二义性。

当今时代,为了应用程序的国际化,应该提倡使用UNICODE来编写程序!

VC++6.0之前没有关键字wchar_t,用unsigned short表示WCHAR;

VC++7.0之后有了关键字wchar_t,用来表示WCHAR,及宽字符;

Unicode 是支持所有字符集(包括无法以单个字节表示的字符集)的规范。为国际市场编程时应考虑使用 Unicode 或多字节字符集 (MBCS),或使程序能够通过更改开关来生成支持两种字符集之一的程序。

宽字符是双字节多语言字符代码。在当今的全球计算业内使用的大多数字符(包括技术符号和特殊的发布字符),都可以根据 Unicode 规范表示为宽字符形式。无法以 1 个宽字符表示的字符可以通过 Unicode 的代理项功能以 Unicode 对表示。由于每个宽字符总是以固定的 16 位大小表示,因此使用宽字符可以简化使用国际字符集进行的编程。

宽字符字符串表示为一个 wchar_t[] 数组并由 wchar_t* 指针指向它。可以通过用字母 L 作为字符的前缀将任何 ASCII 字符表示为宽字符形式。例如,L'0' 是终止宽(16 位)NULL 字符。同样,可以通过用字母 L 作为 ASCII 字符串的前缀 (L"Hello") 将任何 ASCII 字符串表示为宽字符字符串形式。

通常,宽字符在内存中占用的空间比多字节字符多,但处理速度更快,因为很多系统的内核包括Windows NT内核都是从底层向上使用Unicode编码的。另外,在多字节编码中一次只能表示一个区域设置,Unicode编码可以毫无障碍的在世界上任何书面语言的字符中转换。


本文标签: 编码 字符 字节