🔖
perl unpack(h)を他言語で再現するのは面倒だった
wiki engineでは、日本語タイトルをそのまま扱うために、なんらかの方法でASCII文字に変換することはよくある。
例えば次の通り。
とある事情で、タイトルだけ別のプログラムで利用しようと思ったのだが、ここではまった。
python3 bytes.formhex()で済むだろうと思い込んでた。ChatGPTもそういってた
しかしエンコードしたはずの文字列は期待したように読めなかったのだ。
そこまででようやく気づいたのは unpack(h) は小生が現在愛用するpython3には存在しないのだ。
h 16 進数文字列 (低位ニブルが先)。
H 16 進数文字列 (高位ニブルが先)。
ニブルとは4ビットのことで、16進数でいえばただの1桁にあたる。つまりb'1B'は、"B1"に変換されてることを意味する。
一方、pythonではバイトオーダーの話しかしてない。16進数でいえば2桁である。
どうやら2バイト分それぞれ、上下ニブルを入れ替えなければならないらしい。
しかたないので書いた。
def perlunpackh(hex_str: str) -> str:
nowstr = bytearray()
for ii in range(0, len(hex_str), 2):
nib = hex_str[ii:ii+2]
rnib = nib[-1] + nib[0]
byte_val = int(rnib,16)
nowstr.append(byte_val)
nowstr = nowstr.decode("utf-8")
return nowstr
内包表記では書き直せるが、これ以上短くしてもあまり意味がなかったので妥協した。
Discussion