Unicode与GB18030、GBK、GB2312

编码举例-先入为主:

Unicode:4DAE (CJK扩展A)
Unicode PUA:E863(UTF-16BE)
UTF-8:(EF BB BF) E4 B6 AE
UTF-16BE:(FEFF) 4DAE
UTF-16LE:(FFFE) AE4D
UTF-32BE:(0000FEFF) 00004DAE
UTF-32LE:(FFFE0000) AE4D0000
GB18030:FE9F
GBK:FE9F
GB2312:没有


Unicode:3D65 (CJK扩展A)
UTF-8:(EF BB BF) E3 B5 A5
UTF-16BE:(FEFF) 3D65
UTF-16LE:(FFFE) 653D
UTF-32BE:(0000FEFF) 00003D65
UTF-32LE:(FFFE0000) 653D0000
GB18030:8231E230
GBK:没有
GB2312:没有

𠅤
Unicode:20164 (CJK扩展B)
Unicode PUA:E0FC (UTF-16BE)
UTF-8:(EF BB BF) F0 A0 85 A4
UTF-16BE:(FEFF) D840 DD64
UTF-16LE:(FFFE) 40D8 64DD
UTF-32BE:(0000FEFF) 00020164
UTF-32LE:(FFFE0000) 64010200
GB18030:9532A632
GBK:没有
GB2312:没有

𬍛
Unicode:2C35B (CJK扩展E)
Unicode PUA:E352 (UTF-16BE)
搜狗自造字PUA:E058(UTF-16BE)
UTF-8:(EF BB BF) F0 AC 8D 9B
UTF-16BE:(FEFF) D870 DF5B
UTF-16LE:(FFFE) 70D8 5BDF
UTF-32BE:(0000FEFF) 0002C35B
UTF-32LE:(FFFE0000) 5BC30200
GB18030:9931D937
GBK:没有
GB2312:没有

𬱖
Unicode:2CC56 (CJK扩展E)
Unicode PUA:E43E (UTF-16BE)
搜狗自造字PUA:E10E(UTF-16BE)
UTF-8:(EF BB BF) F0 AC B1 96
UTF-16BE:(FEFF) D873 DC56
UTF-16LE:(FFFE) 73D8 56DC
UTF-32BE:(0000FEFF) 0002CC56
UTF-32LE:(FFFE0000) 56CC0200
GB18030:9933C336
GBK:没有
GB2312:没有

𪠽 (口当)
Unicode:2A83D (CJK扩展C)
Unicode PUA:E27B (UTF-16BE)
搜狗自造字PUA:E1D5(UTF-16BE)
UTF-8:(EF BB BF) F0 AA A0 BD
UTF-16BE:(FEFF) D86A DC3D
UTF-16LE:(FFFE) 3DDC 6AD8
UTF-32BE:(0000FEFF) 0002A83D
UTF-32LE:(FFFE0000) 3DA80200
GB18030:98369935
GBK:没有
GB2312:没有

我:
Unicode:6211 (CJK基本区)
UTF-8: (EF BB BF) E6 88 91
UTF-16BE: (FEFF) 6211
UTF-16LE: (FFFE) 1162
UTF-32BE:(0000FEFF) 00006211
UTF-32LE:(FFFE0000) 11620000
GB18030:CED2
GBK:CED2
GB2312:CED2

珺:
Unicode:73FA (CJK基本区)
UTF-8: (EF BB BF) E7 8F BA
UTF-16BE: (FEFF) 73FA
UTF-16LE: (FFFE) FA73
UTF-32BE:(0000FEFF) 000073FA
UTF-32LE:(FFFE0000) FA730000
GB18030:AC42
GBK: AC42
GB2312:没有

UTF编码的BOM:
BOM的用途:BOM是Byte Order Mark的缩写,在UTF-16和UTF-32中需要使用BOM来区分字节顺序,因为CPU有两种系列,一种是大端模式,一种是小端模式(常用设备多为该种模式),在两种不同模式的设备互传文件可能出现无法读取的情况,在文件的最前面添加一个BOM便可判断文件的字节顺序是大端序还是小端序,按照BOM所记录的顺序读取,就不会在读取时出错。UTF-8本身并没有大小端之分,但微软旧版Windows记事本中的UTF-8编码使用了UTF-8的BOM。

各个UTF的BOM:
UTF-8: EF BB BF
UTF-16BE: FEFF
UTF-16LE: FFFE
UTF-32BE: 0000FEFF
UTF-32LE: FFFE0000
LE(Little Endian):小端序存储
BE(Big Endian):大端序存储

微软Windows记事本:
*旧版记事本
ANSI:为使Windows系统支持多国语言设立的编码,在不同地区的系统下,编码各不相同,可通过设置Windows语言和地区改变编码,在中文简体系统下一般指GBK,CodePage为936,GB18030的CodePage为54936。
Unicode:指UTF16-LE,UTF-16小端序,在UCS-2下,定长表示,只有BMP平面,UTF-16的编码几乎和Unicode编码一致,因此当时把UTF-16LE写成Unicode。
Unicode big endian:指UTF16-BE,UTF-16大端序,在UCS-2下,定长表示,只有BMP平面,UTF-16的编码几乎和Unicode编码一致,因此当时把UTF-16BE写成Unicode big endian。
UTF-8:带有BOM的UTF-8编码。

*新版记事本(Windows10 1909版):
ANSI:为使Windows系统支持多国语言设立的编码,在不同地区的系统下,编码各不相同,可通过设置Windows语言和地区改变编码,在中文简体系统下一般指GBK,CodePage为936,GB18030的CodePage为54936。
UTF16-BE:UTF-16大端序
UTF16-LE:UTF-16小端序
UTF-8:UTF-8编码
UTF-8 with BOM:带有BOM的UTF-8编码

Unicode的平面
Unicode有17个平面,即第0平面(0000-FFFF)到第16平面(100000-10FFFF)。
第0平面称为BMP(Basic Multilingual Plane)平面,又称为基本多文种平面,其范围为0000-FFFF,第0平面外的平面统称为辅助平面。
第1辅助平面称为SMP(Supplementary Multilingual Plane)平面,又称为多文种补充平面,主要摆放拼音文字及符号,其范围为10000-1FFFF。
第2辅助平面称为SIP(Supplementary Ideographic Plane)平面,又称为表意文字补充平面,其范围为20000-2FFFF。
第3辅助平面称为TIP(Tertiary Ideographic Plane)平面,又称为表意文字第三平面,其范围为30000-3FFFF。
第4至13辅助平面尚未使用。
第14辅助平面称为SSP(Supplementary Special-purpose Plane)平面,又称为特殊用途补充平面,摆放语言标签(Language Tags)和异体字选择器(Variation Selectors),这些都是控制字符,其范围为E0000-EFFFF。
第15辅助平面为私人使用区:补充私人使用区-A (F0000-FFFFF)- Supplementary Private Use Area-A
第16辅助平面为私人使用区:补充私人使用区-B(100000-10FFFF)- Supplementary Private Use Area-B

UTF-8与UTF-16:
Unicode转UTF-8(最多4字节,BMP平面最多只使用3个字节):
Unicode:0000 0000 - 0000 007F
UTF-8:0xxxxxxx
Unicode:0000 0080 - 0000 07FF
UTF-8:110xxxxx 10xxxxxx
Unicode:0000 0800 - 0000 FFFF
UTF-8:1110xxxx 10xxxxxx 10xxxxxx
Unicode:0001 0000 - 0010 FFFF
UTF-8:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
转换时将16进制的Unicode转成2进制,按范围逐一填入上表的x中。汉字在UTF-8中,在BMP平面的需要3个字节表示,在SIP和TIP平面中使用4个字节表示。

Unicode转UTF-16:
Unicode BMP平面不用转换,BMP以外的平面需要使用UTF-16代理编码:
UTF-16代理UTF-16 Surrogates (D800-DFFF)
-高半区代理(D800-DBFF)
-低半区代理(DC00-DFFF)
Unicode编码的U+10000相当于UTF-16编码的D800 DC00
从Unicode代码点到代理项对转换:
1、获取Unicode代码点值,减去0x10000,转成20位二进制,分成两个高低代理的10位二进制
2、高代理项10位二进制转成16进制,从高代理项加上0xD800
3、低代理项10位二进制转成16进制,从低代理项加上0xDC00
从代理项对到Unicode代码点转换:
1、从高代理项减去0xD800,获取有效10位二进制
2、从低代理项减去0xDC00,获取有效10位二进制
3、组合成20位二进制转16进制,加上0x10000,获取Unicode代码点值

Unicode CJK表意文字一览
中日韩统一表意文字基本区URO(20992个码位)
首发unicode版本:1.0.1
发布时间:1992年6月
范围:4E00-9FFF(BMP平面)
字数:
20902字(1.0.1版),1992年6月。(4E00-9FA5)
20924字(4.1版),2005年3月31日。(4E00-9FBB),增加22字
20932字(5.1版),2008年4月4日。(4E00-9FC3),增加8字
20940字(5.2版),2009年10月1日。(4E00-9FCB),增加8字
20941字(6.1版),2012年1月31日。(4E00-9FCC),增加1字
20950字(8.0版),2015年6月17日。(4E00-9FD5),增加9字
20971字(10.0版),2017年6月20日。(4E00-9FEA),增加21字
20976字(11.0版),2018年6月5日。(4E00-9FEF),增加5字
20989字(13.0版),2020年3月10日。(4E00-9FFC),增加13字
20992字(14.0版),2021年9月14日。(4E00-9FFF),增加3字
所有码位均用完。

中日韩统一表意文字扩展A(6592个码位)
首发unicode版本:3.0
发布时间:1999年9月
范围:3400-4DBF(BMP平面)
字数:
6582字(3.0版),1999年9月。(3400-4DB5)
6592字(13.0版),2020年3月10日。(3400-4DBF),增加10字
所有码位均用完。

中日韩统一表意文字扩展B(42720个码位)
首发unicode版本:3.1
发布时间:2001年3月
范围:20000-2A6DF(SIP平面)
字数:
42711字(3.1版),2001年3月。(20000-2A6D6)
42718字(13.0版),2020年3月10日。(20000-2A6DD),增加7字
42720字(14.0版),2021年9月14日。(20000-2A6DF),增加2字
所有码位均用完。

中日韩统一表意文字扩展C(4160个码位)
首发unicode版本:5.2
发布时间:2009年10月1日
范围:2A700-2B73F(SIP平面)
字数:
4149字(5.2版),2009年10月1日。(2A700-2B734)
4153字(14.0版),2021年9月14日。(2A700-2B738),增加4字
4154字(15.0版),2022年9月13日。(2A700-2B739),增加1字
剩余6个保留码位未使用。

中日韩统一表意文字扩展D(224个码位)
首发unicode版本:6.0
发布时间:2010年10月11日
范围:2B740-2B81F(SIP平面)
字数:
222字(6.0版),2010年10月11日。(2B740-2B81D)
剩余2个保留码位未使用。

中日韩统一表意文字扩展E(5776个码位)
首发unicode版本:8.0
发布时间:2015年6月17日
范围:2B820-2CEAF(SIP平面)
字数:
5762字(8.0版),2015年6月17日。(2B820-2CEA1)
剩余14个保留码位未使用。

中日韩统一表意文字扩展F(7488个码位)
首发unicode版本:10.0
发布时间:2017年6月20日
范围:2CEB0-2EBEF(SIP平面)
字数:
7473字(10.0版),2017年6月20日。(2CEB0-2EBE0)
剩余15个保留码位未使用。

中日韩统一表意文字扩展G(4944个码位)
首发unicode版本:13.0
发布时间:2020年3月10日
范围:30000-3134F(TIP平面)
字数:4939字(13.0版),2020年3月10日。(30000-3134A)
剩余5个保留码位未使用。

中日韩统一表意文字扩展H(4192个码位)
首发unicode版本:15.0
发布时间:2022年9月13日
范围:31350-323AF(TIP平面)
字数:4192字(15.0版),2022年9月13日。(31350-323AF)
所有码位均用完。

Unicode的PUA(Private Use Areas):
在Unicode中, 私人使用区指其解释未在Unicode标准中指定,而是由合作用户之间的私人协议决定其用途的一系列码位。Unicode定义了三个私人使用区:一个在基本多文种平面(U+E000-U+F8FF)中,另外两个几乎包含了整个第15和第16平面(分别为U+F0000-U+FFFFD,U+100000-U+10FFFD)。私人使用区字符的分配,可不由字面意义上的私人决定;一些组织已经发布了一些分配计划。但根据其定义,私人使用区相同的代码点可被分配为不同的字符,因此用户可能因安装了某种字体,看到其显示为一种形态,但使用了其他字体的用户可能看到完全不同的字符。

Windows系统对Unicode的字体支持:
Windows XP:初版CJK基本区(4E00-9FA5)及GBK部分收入的扩展A
Windows Vista:扩展B
Windows 7:扩展B
Windows 8:扩展D
Windows 8.1:扩展D
Windows 10:扩展E在《通用规范汉字表》中的108字及之前编码错位的7个字

国标GB码收入汉字的演变简述:
GB2312-1980:发布于1980年,共收录6763字,由区位码加上2020H得到国标码,再加上8080H,得到在计算机内部使用的机内码构成。
GBK-1995:发布于1995年,收录了21003个汉字,收入了GB13000-1993编码中的所有汉字,BIG5编码的汉字也因此收入其中,“珺”、“瓅”等字从此进入国标码,该编码中有52个汉字在GBK发布时Unicode没有收入,比如“䶮”字,临时使用Unicode PUA编码E863表示,1999年9月后,这52个汉字在Unicode CJK扩展A收入,但现在仍然常常在GBK转Unicode编码时,会将其转成Unicode PUA临时编码,反向将Unicode CJK扩展A的编码转换到GBK时可能会转成“?”,现今可用于转换GBK编码的范围常被固定在初版基本区的范围(4E00-9FA5),CJK基本区以后固定的范围是(4E00-9FFF),类似于“䶮”字的52个GBK汉字由于在CJK扩展A内而得不到转码,最终会转成“?”。在制定GBK时,Unicode中还没有这些字符,所以使用了私用区(PUA)的码位,这80个字符的码位是0xE815-0xE864。后来,Unicode将52个汉字收录到“CJK统一汉字扩充A”。28个部首中有14个部首被收录到“CJK部首补充区”。所以,这些字符都有两个编码,一个为Unicode正式码,另一个为私用区(PUA)临时码。其中8个部首被收录到“CJK统一汉字URO+”的新增区域,即0x9FA6-0x9FFF。还有6个部首被Unicode收录到“CJK统一汉字扩充B区”。
GB18030-2000:发布于2000年,收录了27533个汉字,将Unicode CJK 扩展A的汉字加入,扩展A的汉字非GBK部分使用4字节编码,并将此定为强制标准。该标准支持单字节、双字节、四字节编码。常用输入法均支持该标准,即初版CJK基本区+CJK扩展A。
GB18030-2005:发布于2005年,收录了70244个汉字,将Unicode CJK 扩展B的汉字加入,扩展B的汉字使用4字节编码,扩展A部分及以下为强制标准,其余为推荐标准。该标准支持单字节、双字节、四字节编码。

《通用规范汉字表》在CJK初版基本区外的收字:
(CJK初版基本区是指范围在4E00-9FA5的汉字,在1992年的Unicode1.0.1中首次发布,1993年ISO/IEC10646-1:1993也同步采用此范围,GB13000.1-1993也同步采用该范围,Unicode14.0首次将CJK基本区的范围填满为4E00-9FFF。)
CJK基本区汉字补充:3字
鿍鿎鿏
CJK-A: 77字
㑇㑊㕮㘎㙍㙘㙦㛃㛚㛹㟃㠇㠓㤘㥄㧐㧑㧟㫰㬊㬎㬚㭎㭕㮾㰀㳇㳘㳚㴔㵐㶲㸆㸌㺄㻬㽏㿠䁖䂮䃅䃎䅟䌹䎃䎖䏝䏡䏲䐃䓖䓛䓨䓫䓬䗖䗛䗪䗴䜣䝙䢺䢼䣘䥽䦃䲟䲠䲢䴓䴔䴕䴖䴗䴘䴙䶮
CJK-B: 36字
𠅤𠙶𠳐𡎚𡐓𣗋𣲗𣲘𣸣𤧛𤩽𤫉𥔲𥕢𥖨𥻗𦈡𦒍𦙶𦝼𦭜𦰡𧿹𨐈𨙸𨚕𨟠𨭉𨱇𨱏𨱑𨱔𨺙𩽾𩾃𩾌
CJK-C: 44字
𪟝𪣻𪤗𪨰𪨶𪩘𪾢𫄧𫄨𫄷𫄸𫇭𫌀𫍣𫍯𫍲𫍽𫐄𫐐𫐓𫑡𫓧𫓯𫓶𫓹𫔍𫔎𫔶𫖮𫖯𫖳𫗧𫗴𫘜𫘝𫘦𫘧𫘨𫘪𫘬𫚕𫚖𫚭𫛭
CJK-D: 8字
𫞩𫟅𫟦𫟹𫟼𫠆𫠊𫠜
CJK-E: 108字
𫢸𫫇𫭟𫭢𫭼𫮃𫰛𫵷𫶇𫷷𫸩𬀩𬀪𬂩𬃊𬇕𬇙𬇹𬉼𬊈𬊤𬌗𬍛𬍡𬍤𬒈𬒔𬒗𬕂𬘓𬘘𬘡𬘩𬘫𬘬𬘭𬘯𬙂𬙊𬙋𬜬𬜯𬞟𬟁𬟽𬣙𬣞𬣡𬣳𬤇𬤊𬤝𬨂𬨎𬩽𬪩𬬩𬬭𬬮𬬱𬬸𬬹𬬻𬬿𬭁𬭊𬭎𬭚𬭛𬭤𬭩𬭬𬭯𬭳𬭶𬭸𬭼𬮱𬮿𬯀𬯎𬱖𬱟𬳵𬳶𬳽𬳿𬴂𬴃𬴊𬶋𬶍𬶏𬶐𬶟𬶠𬶨𬶭𬶮𬷕𬸘𬸚𬸣𬸦𬸪𬹼𬺈𬺓

字体与输入法:
字体文件用于显示对应Unicode编码的字形,输入法则是通过输入码(拼音、五笔、语音、手写)来搜索寻找对应的Unicode编码,以字符形式插入文本,操作系统没有该编码的字体,则显示为字体指定的缺字符号。Word和写字板可通过输入16进制Unicode编码,然后同时按Alt+X键将Unicode编码转成对应的字符。

Unicode辅助平面与GB18030转换:
GB18030转Unicode:
10进制转16进制(
(GB18030第一字节的10进制-144)*12600
+(GB18030第二字节的10进制-48)*1260
+(GB18030第三字节的10进制-129)*10
+(GB18030第四字节的10进制-48)
+65536)

Uncode转GB18030:
A=Unicode编码(16进制)
B=INT((16进制转10进制(A)-65536)/12600)
C=MOD((16进制转10进制(A)-65536),12600)
D=INT(C/1260)
E=MOD(C,1260)
F=INT(E/10)
G=MOD(E,10)
第一字节=10进制转16进制(B+144)
第二字节=10进制转16进制(D+48)
第三字节=10进制转16进制(F+129)
第四字节=10进制转16进制(G+48)

Unicode字表:
https://www.unicode.org/charts/
整体字表:
https://www.unicode.org/Public/15.0.0/charts/CodeCharts.pdf

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 C++ 算法,用于将 GB18030 编码转换成 Unicode 编码: ```c++ #include <iostream> #include <string> #include <vector> typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; // GB18030 编码转换成 Unicode 编码 std::wstring GB18030ToUnicode(const std::string& str) { std::wstring result; std::vector<BYTE> bytes(str.begin(), str.end()); int i = 0; while (i < bytes.size()) { if (bytes[i] <= 0x7F) { // ASCII 字符 result += (wchar_t)bytes[i]; i++; } else if (bytes[i] >= 0x81 && bytes[i] <= 0xFE) { // 双字节字符 if (i + 1 < bytes.size()) { WORD w = ((WORD)bytes[i] << 8) | ((WORD)bytes[i + 1]); if (w >= 0x8140 && w <= 0xFEFE && w != 0x817F && w != 0x8180) { // GBK/GB2312 编码范围内的汉字 result += (wchar_t)(0x4E00 + (w - 0x8140) / 0x100 * 0x40 + (w - 0x8140) % 0x100); } else if (w >= 0x8130 && w <= 0xA0FE) { // GB18030 编码范围内的汉字 DWORD dw = ((DWORD)w - 0x8130) / 10 * 0x100 + ((DWORD)w - 0x8130) % 10 + 0x10000; result += (wchar_t)dw; } i += 2; } else { break; } } else if (bytes[i] >= 0x80 && bytes[i] <= 0xBF) { // 单字节字符,不是汉字 result += (wchar_t)bytes[i]; i++; } else if (bytes[i] >= 0xC0 && bytes[i] <= 0xDF) { // 双字节字符,不是汉字 if (i + 1 < bytes.size()) { WORD w = ((WORD)bytes[i] << 8) | ((WORD)bytes[i + 1]); result += (wchar_t)(0x80 + (w - 0xC0A0)); i += 2; } else { break; } } else if (bytes[i] >= 0xE0 && bytes[i] <= 0xEF) { // 三字节字符 if (i + 2 < bytes.size()) { DWORD dw = ((DWORD)bytes[i] << 16) | ((DWORD)bytes[i + 1] << 8) | (DWORD)bytes[i + 2]; result += (wchar_t)dw; i += 3; } else { break; } } else { break; } } return result; } ``` 下面是一个简单的 C++ 算法,用于将 Unicode 编码转换成 GB18030 编码: ```c++ #include <iostream> #include <string> #include <vector> typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; // Unicode 编码转换成 GB18030 编码 std::string UnicodeToGB18030(const std::wstring& str) { std::string result; for (int i = 0; i < str.size(); i++) { if (str[i] <= 0x7F) { // ASCII 字符 result += (char)str[i]; } else if (str[i] >= 0x4E00 && str[i] <= 0x9FA5) { // GBK/GB2312 编码范围内的汉字 BYTE b1 = (BYTE)((str[i] - 0x4E00) / 0x40 + 0x81); BYTE b2 = (BYTE)((str[i] - 0x4E00) % 0x40 + 0x40); result += b1; result += b2; } else { // GB18030 编码范围内的汉字 DWORD dw = (DWORD)str[i]; if (dw >= 0x10000 && dw <= 0x10FFFF) { dw -= 0x10000; BYTE b1 = (BYTE)(dw / 0x1000 + 0x90); BYTE b2 = (BYTE)((dw % 0x1000) / 0x40 + 0x81); BYTE b3 = (BYTE)((dw % 0x1000) % 0x40 + 0x30); result += b1; result += b2; result += b3; } } } return result; } ``` 需要注意的是,这两个算法只是简单的示例代码,不能处理所有情况。在实际应用中,需要根据具体需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值