在上世纪八十年代的时候,发送Email只允许使用7bits(即每个字节的8bits,最高位固定为0,只使用后面7bits)。早期的一些电脑操作系统也是基于ASCII(每字节最高位固定为0)。我们知道1字节等于8bits,对于英语国家来说,ASCII编码已经能够满足日常邮件内容。ASCII只有128种字母或符号,采用7bits足够了。但是,对于中文来说只使用7bits是远远不够的。当时已经存在GB2312字符集,每个中文汉字可以使用2字节(16bits)表示出来,GB2312总共定义了6000多个中文汉字或标点符号,足够日常使用。比如“国家”的“国”字,在GB2312中编码为0xB9FA,二进制表示为“10111001 11111010”,占据两个字节。
但是问题在于,“国”字的编码,两个字节把8bits全都用上了,每个字节的最高位是1,这种情况下当时的Email无法支持传输。那么问题就来了,怎样在满足最高位不使用,只使用后面7bits的情况下,把中文汉字表示出来?在这样的背景下,诞生了HZ-GB-2312编码。
HZ-GB-2312编码其实仅仅只是将已经存在的GB2312字符集使用另一种方式表示出来而已。GB2312的特点是,所有的中文汉字和符号,每字节最高位都是1(byte值大于128),那么一个比较直觉的方案是,所有的中文字符,把最高位的1全都换成0,这样就只利用了剩下的7bits。当然,直接替换成0,会导致GB2312的汉字和ASCII中的字母相冲突,因此,在中文的开端和结尾需要带上转义字符。HZ-GB-2312的编码方案也正是这种思路。
HZ-GB-2312的编码规则已经收录到RFC规范内,详情可查阅链接:https://tools.ietf.org/pdf/rfc1843.pdf 。如果你懒得看一大堆英文,也可以继续往下瞧,我用尽量通俗的语言解释一下HZ-GB-2312的细节。
HZ-GB-2312属于GB2312的另一种编码规则,特点就是不使用一个byte的最高位(即最高位永远为0)。GB2312中所有中文都是双字节编码,并且第一个字节值域在0xA1至0xF7,第二个字节值域在0xA1至0xFE,可见GB2312所有中文编码所有byte都是高位(最高位永远为1)。HZ-GB-2312编码方法是先把GB2312的编码值,两个字节都减去128(即最高位的1去掉,例如0xA1变为0x21),然后用‘~{’(即0x7E7B)和'~}'(即0x7E7D)把中文包裹在里面。
举例说明:
对于汉字“一”,他的GB2312编码为0xD2BB,如果两个byte各减去128,得到0x523B,因此“一”的HZ-GB-2312编码为0x7E7B523B7E7D。需要注意的是,一组'~{'和'~}'内部可以包裹任意个中文汉字。不在'~{'和'~}'包裹范围内的的部分都是ASCII编码格式。
另外,
1 连续两个波浪线(即'~~'),会被解释为单个波浪线(第一个波浪线看作转义符号)
2 波浪线加换行符(即'~\n'),会被解释为续行标记,不会被打印,不做显示。这个的作用是可以在编码的时候,把一行比较长的文字编码为多个HZ-GB-2312的短行。
3 也就是说在HZ-GB-2312编码中,波浪线后面只可能跟着'~','\n','{','}',除这4种之外,出现其他任何字符都是不可能的。
我们再来看一个完整的中英文混合语句的编码:
在上面这个中英文混合语句中,我们可以看到中英文交替时候的转义字符,一组转义字符内可以放置任意个中文汉字的编码。另外,由于波浪线有了特殊含义,所以一个波浪线被编码为两个波浪线(第一个为转义字符)。最终,在email传输过程中,我们只需要把编码后的句子传到目标计算机,再通过解码,就可以将源字符串复原。编码后的句子完全是由ASCII字符组成,符合“只使用最低7bits”的要求。
HZ-GB-2312编码与ASCII不兼容,因为波浪线被赋予了特殊意义。如果不计入波浪线的话,HZ-GB-2312和ASCII是兼容的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。