字符编码相关的知识
1.编码的基础知识
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则。
字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字(计算机内部是以二进制存储的)。
字符编码(英语:Character encoding)也称字集码,是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。例如将拉丁字母表编码成摩斯电码和ASCII。
总结:也就是说,字符编码就是定义了一个编码表格,它为每种语言中的每个字符设定了统一并且唯一的二进制编码。
例如:unicode编码表中定义了: "4e94"表示中文字符”五"。
而在编码系统中,可分为编码方式和实现方式两个层次。(编码方式可以简单理解为:如何划分字符集和对应的二进制编码,也就是对不同的语言和字符做一定的分类,不同的分类在不同编码区中,这样脉络就会很清晰;而实现方式可以理解为:计算机如何存储、传输、编码和解码这些二进制编码,继而找到对应的字符)。
常见字符集名称(字符编码):ASCII字符集、GB2312字符集、BIG5字符集、 GB 18030字符集、Unicode字符集等。
(1)ASCII字符集编码:
名称由来
ASCII(American Standard Code for Information Interchange,美国信息互换标准编码)是基于罗马字母表的一套电脑编码系统。
特点
它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO 646。
包含内容
控制字符:回车键、退格、换行键等。
可显示字符:英文大小写字符、阿拉伯数字和西文符号。
技术特征
32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。
65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
扩展字符集
7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。
ASCII扩展字符集:它是从ASCII字符集扩充出来的,扩充后的符号增加了表格符号、计算符号、希腊字母和特殊的拉丁符号。
(2)GB2312字符集编码:
名称由来
GB2312又称为GB2312-80字符集,全称为《信息交换用汉字编码字符集·基本集》,由原中国国家标准总局发布,1981年5月1日实施。
特点
GB2312是中国国家标准的简体中文字符集。它所收录的汉字已经覆盖99.75%的使用频率,基本满足了汉字的计算机处理需要。在中国大陆和新加坡获广泛使用。
包含内容
GB2312收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共 7445 个图形字符。其中包括6763个汉字,其中一级汉字3755个,二级汉字3008个;包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。
技术特征
(1)分区表示:
基本集共收入汉字6763个和非汉字图形字符682个。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位来对汉字进行编码,称为区位码。
各区包含的字符如下:01-09区为特殊符号;16-55区为一级汉字,按拼音排序;56-87区为二级汉字,按部首/笔画排序;10-15区及88-94区则未有编码。
(2)双字节表示(存储方法,实现方法)
两个字节中前面的字节为第一字节,后面的字节为第二字节。习惯上称第一字节为“高字节” ,而称第二字节为“低字节”。
“高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上0xA0)。
编码举例
以GB2312字符集的第一个汉字“啊”字为例,它的区号16,位号01,则区位码是1601,在大多数计算机程序中,高字节和低字节分别加0xA0得到程序的汉字处理编码0xB0A1。计算公式是:0xB0=0xA0+16, 0xA1=0xA0+1。
(3)BIG5字符集编码:
名称由来
又称大五码或五大码,1984年由台湾财团法人信息工业策进会和五家软件公司宏碁 (Acer)、神通 (MiTAC)、佳佳、零壹 (Zero One)、大众 (FIC)创立,故称大五码。
Big5码的产生,是因为当时台湾不同厂商各自推出不同的编码,如倚天码、IBM PS55、王安码等,彼此不能兼容;另一方面,台湾政府当时尚未推出官方的汉字编码,而中国大陆的GB2312编码亦未有收录繁体中文字。
特点
Big5字符集共收录13,053个中文字,该字符集在中国台湾使用。耐人寻味的是该字符集重复地收录了两个相同的字:“兀”(0xA461及0xC94A)、“嗀”(0xDCD1及0xDDFC)。
编码方法
Big5码使用了双字节储存方法,以两个字节来编码一个字。第一个字节称为“高位字节”,第二个字节称为“低位字节”。高位字节的编码范围0xA1-0xF9,低位字节的编码范围0x40-0x7E及0xA1-0xFE。
各编码范围对应的字符类型如下:0xA140-0xA3BF为标点符号、希腊字母及特殊符号,另外于0xA259-0xA261,存放了双音节度量衡单位用字:兙兛兞兝兡兣嗧瓩糎;0xA440-0xC67E为常用汉字,先按笔划再按部首排序;0xC940-0xF9D5为次常用汉字,亦是先按笔划再按部首排序。
局限性
尽管Big5码内包含一万多个字符,但是没有考虑社会上流通的人名、地名用字、方言用字、化学及生物科等用字,没有包含日文平假名及片假名字母。
例如台湾视“着”为“著”的异体字,故没有收录“着”字。康熙字典中的一些部首用字(如“亠”、“疒”、“辵”、“癶”等)、常见的人名用字(如“堃”、“煊”、“栢”、“喆”等) 也没有收录到Big5之中。
(4)GB 18030字符集编码:
名称由来
GB 18030的全称是GB18030-2000《信息交换用汉字编码字符集基本集的扩充》,是我国政府于2000年3月17日发布的新的汉字编码国家标准,2001年8月31日后在中国市场上发布的软件必须符合本标准。
特点
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。
包含内容
双字节部分收录内容主要包括GB13000.1全部CJK汉字20902个、有关标点符号、表意文字描述符13个、增补的汉字和部首/构件80个、双字节编码的欧元符号等。四字节部分收录了上述双字节字符之外的,包括CJK统一汉字扩充A在内的GB 13000.1中的全部字符。
(5)Unicode字符集编码:
名称由来
Unicode字符集编码是Universal Multiple-Octet Coded Character Set 通用多八位编码字符集的简称,是由一个名为 Unicode 学术学会(Unicode Consortium)的机构制订的字符编码系统,支持现今世界各种不同语言的书面文本的交换、处理及显示。该编码于1990年开始研发,1994年正式公布,最新版本是2012年1月31日的Unicode 6.1。
特征
Unicode是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
编码方法
(1)Unicode 标准始终使用十六进制数字。在表示一个Unicode的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。在基本多文种平面(英文为 Basic Multilingual Plane,简写 BMP。它又简称为“零号平面”, plane 0)里的所有字符(是Unicode中的一个编码区段),要用四位十六进制数,共支持六万多个字符(例如U+4AE0);在零号平面以外的字符则需要使用五位或六位十六进制数了。旧版的Unicode标准使用相近的标记方法,但却有细微的差异:在Unicode 3.0里使用“U-”然后紧接着八位数,而“U+”则必须随后紧接着四位数。“
(2)”&#“ + 十进制数表示法。
UTF-8 编码
UTF-8是Unicode的其中一个使用方式。 UTF是 Unicode Tranformation Format,即把Unicode转做某种格式的意思。
UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的Unicode能够在现存的处理单字节的系统上正确传输。
UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。辅助平面字符则使用4字节。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。
比较
UTF-16 和 UTF-32 编码
UTF-32、UTF-16和 UTF-8 是 Unicode 标准的编码字符集的字符编码方案,UTF-16 使用一个或两个未分配的 16 位代码单元的序列对 Unicode 代码点进行编码;UTF-32 即将每一个 Unicode 代码点表示为相同值的 32 位整数。
Unicode编码输入
除了输入法外,操作系统会提供几种方法输入Unicode。像是Windows 2000之后的Windows系统就提供一个可点击的表。例如在Microsoft Word或者金山WPS之下,按下Alt键不放,输入 0 和某个字符的 Unicode 编码(十进制),再松开 Alt 键即可得到该字符,如Alt + 033865会得到Unicode字符“叶”(繁体)。另外按Alt + X 组合键,MS Word 也会将光标前面的字符同其十六进制的四位 Unicode 编码进行互相转换。
2.big-endian和little-endian
在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。
不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序。
最常见的有两种:
1. Little-endian:将低序字节存储在起始地址(低位编址)
2. Big-endian:将高序字节存储在起始地址(高位编址)
LE(little-endian):
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位
BE(big-endian):
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去
例子1:在内存中双字0x01020304(DWORD)的存储方式。
内存地址4000 4001 4002 4003
LE04030201
BE01020304
注:每个地址存1个字节,每个字有4个字节。2位16进制数是1个字节(0xFF=11111111)。
例子2:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
big-endianlittle-endian
0x00000x120xcd
0x00010x230xab
0x00020xab0x34
0x00030xcd0x12
x86系列的CPU都是little-endian的字节序。
3.C#字符编码的长度
(1)Encoding.UTF8:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。
(2)Encoding.UTF7:一个英文字符等于一个字节,一个中文(含繁体)等于五个字节。
(3)Encoding.UTF32:一个英文字符等于四个字节,一个中文(含繁体)等于四个字节。
(4)Encoding.Unicode:一个英文等于两个字节,一个中文(含繁体)等于两个字节。
(5)Encoding.BigEndianUnicode:一个英文等于两个字节,一个中文(含繁体)等于两个字节。
(6)Encoding.ASCII:一个英文等于1个字节,一个字符等于1个字节。

浙公网安备 33010602011771号