在 Python 中将 JIS X 208 代码转换为 UTF-8
Convert JIS X 208 code to UTF-8 in Python
假设我有这个汉字“亜”,它以十六进制形式在 JIS X 208 代码中表示:0x3021。我希望我的 Python 程序将该代码转换成它的 UTF-8 格式 E4BA9C,这样我就可以将该字符串(URL-编码)传递到我的 url 中,就像这样
http://jisho.org/api/v1/search/words?keyword=%E4%BA%9C
我正在使用 Python 2.7.12,但我也对 Python 3 解决方案持开放态度
这些是在 ISO 2022 编解码器下访问的。
>>> '亜'.encode('iso2022_jp')
b'\x1b$B0!\x1b(B'
如果我看到那些字节没有被转义序列包围,我就必须知道正在使用哪个版本的 JIS X 0208,但无论如何我此时完全是在维基百科上进行模式匹配。
>>> b = b'3$B' + bytes.fromhex('3021')
>>> c = b.decode('iso2022_jp')
>>> c
'亜'
>>> urllib.parse.quote(c)
'%E4%BA%9C'
(这是 Python 3.)
这个解决方案可能不是标准的,但它似乎有效。
代码
import urllib.parse
def jis_to_euc_jp(jis_hex: str):
"""
You can find the rules from this website: https://pentan.info/doc/jis_list.html
8080 = A1A1 - 2121
4B8080 = 8FA1C1 - 442141
"""
int_jis = int(jis_hex, 16)
step = int('8080', 16) if int_jis <= int('7426', 16) else int('4B8080', 16)
return hex(int_jis + step).upper()[2:] # 0X3021 -> 3021
def eucjp_to_utf_16be(eucjp_hex: str):
byte_ch = bytes.fromhex(eucjp_hex)
real_char = byte_ch.decode('euc_jp') # '亜'
# code = real_str.encode('utf-8').hex().upper() # E4BA9C
return real_char
def main():
for v in ['亜'.encode('utf-8').hex().upper(), # when glyph is know. E4BA9C
# only know jis code, to find the real char
jis_to_euc_jp('3021'), # B0A1 # the Standard Encodings is provided euc-jp turn to utf-16be, so we need to know the relation between JIS and euc-jp
eucjp_to_utf_16be(jis_to_euc_jp('3021'))
]:
print(urllib.parse.quote(v))
if __name__ == '__main__':
main()
E4BA9C
B0A1
%E4%BA%9C
参考资料
假设我有这个汉字“亜”,它以十六进制形式在 JIS X 208 代码中表示:0x3021。我希望我的 Python 程序将该代码转换成它的 UTF-8 格式 E4BA9C,这样我就可以将该字符串(URL-编码)传递到我的 url 中,就像这样
http://jisho.org/api/v1/search/words?keyword=%E4%BA%9C
我正在使用 Python 2.7.12,但我也对 Python 3 解决方案持开放态度
这些是在 ISO 2022 编解码器下访问的。
>>> '亜'.encode('iso2022_jp')
b'\x1b$B0!\x1b(B'
如果我看到那些字节没有被转义序列包围,我就必须知道正在使用哪个版本的 JIS X 0208,但无论如何我此时完全是在维基百科上进行模式匹配。
>>> b = b'3$B' + bytes.fromhex('3021')
>>> c = b.decode('iso2022_jp')
>>> c
'亜'
>>> urllib.parse.quote(c)
'%E4%BA%9C'
(这是 Python 3.)
这个解决方案可能不是标准的,但它似乎有效。
代码
import urllib.parse
def jis_to_euc_jp(jis_hex: str):
"""
You can find the rules from this website: https://pentan.info/doc/jis_list.html
8080 = A1A1 - 2121
4B8080 = 8FA1C1 - 442141
"""
int_jis = int(jis_hex, 16)
step = int('8080', 16) if int_jis <= int('7426', 16) else int('4B8080', 16)
return hex(int_jis + step).upper()[2:] # 0X3021 -> 3021
def eucjp_to_utf_16be(eucjp_hex: str):
byte_ch = bytes.fromhex(eucjp_hex)
real_char = byte_ch.decode('euc_jp') # '亜'
# code = real_str.encode('utf-8').hex().upper() # E4BA9C
return real_char
def main():
for v in ['亜'.encode('utf-8').hex().upper(), # when glyph is know. E4BA9C
# only know jis code, to find the real char
jis_to_euc_jp('3021'), # B0A1 # the Standard Encodings is provided euc-jp turn to utf-16be, so we need to know the relation between JIS and euc-jp
eucjp_to_utf_16be(jis_to_euc_jp('3021'))
]:
print(urllib.parse.quote(v))
if __name__ == '__main__':
main()
E4BA9C
B0A1
%E4%BA%9C