GB18030-2022《信息技术 中文编码字符集》于2022年7月19日由国家市场监督管理总局(国家标准化管理委员会)发布,并将于2023年8月1日实施。我依据国标文件,使用Python生成了字符集中全部字符的码位,在此分享给需要码位进行国标测试的朋友们。
国标文件收录的字符以单字节、双字节和四字节编码。码位范围分配如下图所示:
先定义三个函数,分别用来生成单字节、双字节和四字节的码位。注意,四字节生成函数的代码逻辑与单字节和双字节的不同。代码如下:
def _gen_single(x1, y1):
"""
单字节码位生成
:param x1: 一字节起始位置
:param y1: 一字节终止位置
:return: 码位
"""
for b1 in range(x1, y1 + 1):
yield bytearray([b1])
def _gen_double(x1, y1, x2, y2):
"""
双字节码位生成
:param x1: 一字节起始位置
:param y1: 一字节终止位置
:param x2: 二字节起始位置
:param y2: 二字节终止位置
:return: 码位
"""
for b1 in range(x1, y1 + 1):
for b2 in range(x2, y2 + 1):
yield bytearray([b1, b2])
def _gen_four(x1, x2, x3, x4, y1, y2, y3, y4):
"""依次输入起始的1、2、3、4码位和终止的1、2、3、4码位"""
flag = False
for index1, b1 in enumerate(range(x1, y1 + 1)):
min2 = x2 if index1 == 0 else 0x30
for index2, b2 in enumerate(range(min2, 0x39 + 1)):
min3 = x3 if index1 + index2 == 0 else 0x81
for index3, b3 in enumerate(range(min3, 0xFE + 1)):
min4 = x4 if index1 + index2 + index3 == 0 else 0x30
for b4 in range(min4, 0x39 + 1):
yield bytearray([b1, b2, b3, b4])
if (b1, b2, b3, b4) == (y1, y2, y3, y4):
flag = True
break
if flag:
break
if flag:
break
if flag:
break
单字节部分的码位按照GB/T11383-1989的规则分配。码位分配见下图:
生成代码如下:
def gen_single():
"""单字节:0x00-0x7F"""
yield _gen_single(0x00, 0x7F)
def gen_double():
"""生成双字节的码位"""
yield _gen_double(0xA1, 0xA9, 0xA1, 0xFE) # 双字节1区
yield _gen_double(0xB0, 0xF7, 0xA1, 0xFE) # 双字节2区
yield _gen_double(0x81, 0xA0, 0x40, 0x7E) # 双字节3区
yield _gen_double(0x81, 0xA0, 0x80, 0xFE) # 双字节3区
yield _gen_double(0xAA, 0xFE, 0x40, 0x7E) # 双字节4区
yield _gen_double(0xAA, 0xFE, 0x80, 0xA0) # 双字节4区
yield _gen_double(0xA8, 0xA9, 0x40, 0x7E) # 双字节5区
yield _gen_double(0xA8, 0xA9, 0x80, 0xA0) # 双字节5区
yield _gen_double(0xAA, 0xAF, 0xA1, 0xFE) # 双字节用户1区
yield _gen_double(0xF8, 0xFE, 0xA1, 0xFE) # 双字节用户2区
yield _gen_double(0xA1, 0xA7, 0x40, 0x7E) # 双字节用户3区
yield _gen_double(0xA1, 0xA7, 0x80, 0xA0) # 双字节用户3区
def gen_four():
"""生成四字节的码位"""
yield _gen_four(0x81, 0x31, 0x81, 0x32, 0x81, 0x31, 0x99, 0x34) # 维吾尔、哈萨克、柯尔克孜文
yield _gen_four(0x84, 0x30, 0xBA, 0x32, 0x84, 0x30, 0xFE, 0x35) # 维吾尔、哈萨克、柯尔克孜文
yield _gen_four(0x84, 0x31, 0x87, 0x30, 0x84, 0x31, 0x95, 0x30) # 维吾尔、哈萨克、柯尔克孜文
yield _gen_four(0x81, 0x32, 0xE8, 0x34, 0x81, 0x32, 0xFD, 0x31) # 藏文
yield _gen_four(0x81, 0x34, 0xD2, 0x38, 0x81, 0x34, 0xE3, 0x37) # 蒙古文(包括满文、托忒文、锡伯文和阿礼嘎礼字)
yield _gen_four(0x90, 0x34, 0xC5, 0x38, 0x90, 0x34, 0xC7, 0x30) # 蒙古文BIRGA
yield _gen_four(0x81, 0x34, 0xF4, 0x34, 0x81, 0x34, 0xF8, 0x30) # 德宏傣文
yield _gen_four(0x81, 0x34, 0xF9, 0x32, 0x81, 0x35, 0x84, 0x37) # 西双版纳新傣文
yield _gen_four(0x81, 0x35, 0x8B, 0x32, 0x81, 0x35, 0x99, 0x35) # 西双版纳老傣文
yield _gen_four(0x82, 0x35, 0x98, 0x33, 0x82, 0x36, 0x94, 0x35) # 彝文
yield _gen_four(0x82, 0x36, 0x95, 0x35, 0x82, 0x36, 0x9A, 0x32) # 傈僳文
yield _gen_four(0x81, 0x33, 0x9D, 0x36, 0x81, 0x33, 0xB6, 0x35) # 朝鲜文字母
yield _gen_four(0x81, 0x39, 0xA9, 0x33, 0x81, 0x39, 0xB7, 0x34) # 朝鲜文兼容字母
yield _gen_four(0x82, 0x37, 0xCF, 0x35, 0x83, 0x36, 0xBE, 0x36) # 朝鲜文音节
yield _gen_four(0x92, 0x32, 0xC6, 0x36, 0x92, 0x32, 0xD6, 0x35) # 朝鲜文音节
yield _gen_four(0x81, 0x39, 0x8B, 0x32, 0x81, 0x39, 0xA1, 0x35) # 康熙部首
yield _gen_four(0x81, 0x39, 0xEE, 0x39, 0x82, 0x35, 0x87, 0x38) # CJK统一汉字扩充 A
yield _gen_four(0x82, 0x35, 0x8F, 0x33, 0x82, 0x35, 0x96, 0x36) # CJK统一汉字
yield _gen_four(0x95, 0x32, 0x82, 0x36, 0x98, 0x35, 0xF3, 0x36) # CJK统一汉字扩充B
yield _gen_four(0x98, 0x35, 0xF7, 0x38, 0x98, 0x39, 0x9E, 0x36) # CJK统一汉字扩充C
yield _gen_four(0x98, 0x39, 0x9F, 0x38, 0x98, 0x39, 0xB5, 0x39) # CJK统一汉字扩充D
yield _gen_four(0x98, 0x39, 0xB6, 0x32, 0x99, 0x33, 0xFE, 0x33) # CJK统一汉字扩充E
yield _gen_four(0x99, 0x34, 0x81, 0x38, 0x99, 0x39, 0xF7, 0x30) # CJK统一汉字扩充F
对生成代码进行验证
if __name__ == '__main__':
count = 0
for gen in gen_four(): # 验证四字节
for chn in gen:
code_position = [hex(b) for b in chn]
print(code_position, chn.decode('gb18030'))
count += 1
print('====================')
print('共计 {} 个码位'.format(count))