6

解析护照机读码的中文字符

 2 years ago
source link: https://iecho.cc/2022/06/21/chinese-name-parsing-for-passport-machine-readable-zone/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

解析护照机读码的中文字符 | 回声

解析护照机读码的中文字符

2022-06-21 03:39:58

# 生活

xhs-1.jpg
xhs-2.jpg

刷小红书时看到一条使用虚假护照信息进行诈骗的帖子。评论区有网友指出了机读码对应的证件持有人姓名,虽然没有给出具体思路,但考虑到中国人姓名字符集的多样性,不难猜出这是某种国标汉字编码到 ASCII 字符的映射。

passport-sample.jpg

如图所示,护照资料页下方的两行黑色 ASCII 字符串即为机读码 (Machine Readable Zone, MRZ)。其中位于第二行后半部分的、长度为 4 的整数倍的英文字符串是经过编码后的持有人姓名,最多可以储存三个汉字。将汉字的 GB2132 的每个 byte 的两位以十六进制分别映射到字母表中,即可获得对应机读码字符串。例如:"张" -> "\xd5\xc5" (GB2312) -> [d, 5, c, 5] (hex) -> [14, 6, 13, 6] (10) -> NFMF (MRZ)

可以通过下面的 Python 代码实现汉字与机读码互转。

import re


def encode(s: str) -> list[str]:
s = s.encode(encoding='gb2312').hex()
res = []
for c in s:
res.append(chr(ord('a') + int(c, base=16)))
return "".join(res).upper()


def decode(s: str) -> list[str]:
t = []
for c in s:
t.append(format((ord(c) - ord('A')), 'x'))
t = re.findall('.{1,2}', "".join(t))
res = []
for c in t:
res.append(int("0x" + c, 16))
return bytes(res).decode('gb2312')


print(encode('证'))
print(encode('件'))
print(encode('样'))


print(decode('NGKE'))
print(decode('LMPO'))
print(decode('NBPJ'))

1980 年,中国发布了第一个汉字编码标准,也即 GB2312 ,全称 《信息交换用汉字编码字符集·基本集》,通常简称 GB (“国标”汉语拼音首字母), 共收录了 6763 个常用的汉字和字符,此标准于次年5月实施,它满足了日常 99% 汉字的使用需求。

由于有些汉字是在 GB2312 标准发布之后才简化的,还有一些人名、繁体字、日语和朝鲜语中的汉字也没有包括在内,所以,在 GB2312 的基础上添加了这部分字符,就形成了 GBK ,全称 《汉字内码扩展规范》,共收录了两万多个汉字和字符,它完全兼容 GB2312。
GBK 于 1995 年发布,不过它只是 “技术规范指导性文件”,并不属于国家标准。

GB18030 全称《信息技术 中文编码字符集》 ,共收录七万多个汉字和字符, 它在 GBK 的基础上增加了中日韩语中的汉字 和 少数名族的文字及字符,完全兼容 GB2312,基本兼容 GBK。

by 彻底搞明白 GB2312、GBK 和 GB18030 - 知乎

查询字符编码时意外地发现 GBK 和 GB18030 对于 GB2312 完全兼容,因此上文给出的 Python 代码很不严谨,护照可能使用了 GB18030 作为机读码编码。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK