编码格式记录 GBK GB18030 GB2312 ASCII 和 UTF8 UNICODE

  • Post author:
  • Post category:其他




字符编码


网站转码工具




中文编码


兼容性(包含)关系:

GB18030兼容GBK,GBK兼容GB2312,GB2312兼容ASCII


ASCII:

ASCII 是目前最简单也是最通用的字符集,每个字符占据1bytes,

用二进制表示的话最高位必须为0(扩展的ASCII不在考虑范围内),因此ASCII只能表示128个字符,包含数字,大小写字母以及常用的英文标点符号。


GB2312:

GB2312是一个字符集,每个字占据2bytes,为了兼容ASCII这2bytes最高位不可以为0。

全称“信息交换用汉字编码字符集”(GB是“国标”的拼音缩写,2312是国标序号),包含6763个汉字以及682个特殊符号。当文本中的字节小于0x80,为ASCII码,而当文本中的字节大于0x80时,此字节加下一个字节共同表示一个汉字。


GBK:

GBK也是一个字符集,是GB2312的扩充(K是“扩”的拼音缩写),包含21003个汉字(包括繁体字)和984个汉语标点符号、部首,兼容GB2312


GB18030 :

GB18030也是一种字符集,兼容GBK,对GBK多出来的汉字使用4bytes编码。

当然,为了兼容GBK,这个四字节的前两位显然不能与GBK冲突,至2005年发布,GB18030编码的中文文件已经有70244个汉字了,包含了少数民族文字。

类别 码位范围 码位数 字符数 字符类型
双字节部分 第一字节 0xB0-0xF7

第二字节 0xA1-0xFE
6768 6763 汉字
第一字节0x81-0xA0

第二字节0x40-0xFE
6080 6080 汉字
第一字节0xAA-0xFE

第二字节0x40-0xA0
8160 8160 汉字
四字节部分 第一字节0x81-0x82

第二字节0x30-0x39

第三字节0x81-0xFE

第四字节0x30-0x39
6530 6530 CJK统一汉字扩充A
第一字节0x95-0x98

第二字节0x30-0x39

第三字节0x81-0xFE

第四字节0x30-0x39
42711 42711 CJK统一汉字扩充B

我们通常把GB2312字符集这6763字称为“常用字”

而将包含在GBK而不包含在GB2312字符集内的汉字称为“生僻字”。

GBxxx都是我们国家定义的标准,当然只针对我们国家的汉字以及ASCII等。而unicode的出现是为了解决全球的字符编码。




国际编码


编码格式

=

编码格式

+

存储格式

对于GBxxx是将编码和存储方式整合再一起了,我们叫字符集。


UNICODE:

unicode只是编码,不涉及存储格式

而utf-x是基于unicode编码的编码格式,通常包含utf-8、utf-16、utf-32三种。

对于utf-8、utf-16、utf-32三者都使用unicode编码,但存储格式存在差异,它的字符编码中的每个字节都可以小于0x80

在Unicode 5.0的99089个字符中,有71226个字符与汉字有关。它们的分布如下:

Block名称 开始码位 结束码位 字符数
CJK统一汉字 4E00 9FBB 20924
CJK统一汉字扩充A 3400 4DB5 6582
CJK统一汉字扩充B 20000 2A6D6 42711
CJK兼容汉字 F900 FA2D 302
CJK兼容汉字 FA30 FA6A 59
CJK兼容汉字 FA70 FAD9 106
CJK兼容汉字补充 2F800 2FA1D 542

GB2312中的6763个汉字在Unicode中不是连续的,分布在CJK统一汉字字符区(0x4E00-0x9FA5)的20902个汉字中

GBK中的21003个汉字包含在CJK统一汉字字符区的20902个汉字,剩余的101个在不同的区域.


UTF8

UTF-8(Unicode Transformation Format 8-bit)编码是一种可变宽度的编码格式,是用以解决兼容国际字符的一种多字节编码。

对于英文字符较多的论坛则用UTF-8节省空间。另外,如果是外国人访问你的GBK网页,需要下载文语言包支持,访问UTF-8编码的网页则不出现这问题,所以现在一般的网页都是使用utf-8编码。
  • 1.它是一个变长字节(1~4个字节)的编码方式。
  • 2.对于一个字节的编码格式:字节bit[7:0]的bit[7]位必须为0,bit[6:0]这7个位用来编码,即二进制为0b0xxxxxxx。
  • 3.对于n字节(2,3,4个字节)的编码格式,用首字节的bit[7:8-n]位置1,bit[8-n-1]置位0表示字节位数。

    如首字节为0b110xxxxx表示二字节的编码格式。同理0b1110xxxx为三字节格式。剩下的除首字节剩下的字节的bit[7:6]=0b10.其余位用于编码。如编码0b1110xxxx,0b10xxxxxx,0b10xxxxxx表示一个三字节的编码格式,其中x代表的是可编码的位置,可以计算出三字节编码格式共有2^24个编码位置。
字节数 utf-8 编码格式 编号范围
1 0b0xxxxxxx 0x00~0x7F
2 0b110xxxxx 0b10xxxxxx 0x80~0x7FF
3 0b1110xxxx 0b10xxxxxx 0b10xxxxxx 0x800~0xFFFF
4 0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx 0x10000~0x10FFFF


unicode转utf-8步骤:

  1. 首先找到unicode字符编码所在上表中的编号范围。如字符A的unicode编码为0x41,位于utf-8 1字节编码格式(0~127)的编号范围
  2. .将unicode字符编码的二进制位从右到左填入上表中的x位(注意要去掉高位的0)。如字符A(0x41=0b01010001)去掉高位0则为0b1010001。将其填入0b0xxxxxxx后则为0b01010001.也就是utf-8字符A的编码值。

    再举个例子:汉字郭的unicode字符编码为0x90ED(0b10010000,11101101),由0x800 < 0x90ED < 0xFFFF得到它的编码格式为utf-8的3字节编码格式。然后将其二进制0b10010000,11101101填入0b1110xxxx 0b10xxxxxx 0b10xxxxxx后为0b11101001,10000011,10101101=0xE983AD.也就是utf-8字符郭的编码值


c++ unicode转utf-8代码:

/* 
 * utf-8字符编码转化为unicode编码。(2字节模式)
 * pIn:要转换的字符串首地址
 * charsize:接收返回的utf8字符的字节数(1~3)
 * pOut:获取到的UCS2编码,pOut[0]为首字节。
 */
int Utf8ToUCS2(const char *pIn,char *charsize,char *pOut)
{
    uint8_t firstValue = *pIn;
    char *pUCS2 = pOut;

    if(firstValue < 0x80){//0~127 ASCII 1byte
        pUCS2[0] = 0;
        pUCS2[1] = *pIn;
        *charsize = 1;
    }
    else if( (firstValue & 0xE0) == 0xC0){//128~2047 2byte
        if( (pIn[1] & 0xC0) != 0x80){
            return -1;
        }
        pUCS2[0] = (pIn[0] & 0x1F) >> 2;
        pUCS2[1] = (pIn[0] << 6) + (pIn[1] & 0x3F);
        *charsize = 2;
    }
    else if( (firstValue & 0xF0) == 0xE0){//2048~65536 3byte
        if( (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80){
            return -1;
        }
        pUCS2[0] = (pIn[0] << 4) + ((pIn[1] & 0x3F) >> 2);
        pUCS2[1] = (pIn[1] << 6) + (pIn[2] & 0x3F);
        *charsize = 3;
    }
    else {//>3byte不处理,汉字用不到4字节的编码
        *charsize = 0;
        return -1;
    }

    return 0;
}



版权声明:本文为u011888840原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。