[[diary/Kojima]]
・「〜」の文字コード
Windowsな環境で作ったアーカイブファイルをPlamoな環境で開いた場合、ファイル名の文字コードはだいたい問題なくEUC-JPに変換されるのだけど、
たまに "〜” がおかしい場合があるので少し調べてみた。
結構イヤらしいのは、KDEのKonsoleやgnome-terminal, XfceのTerminal上だと問題なく"〜”が表示されるけど、
EmacsやFD経由だとうまく表示されない、という環境依存なところ。
例えば、この a と b というファイルは、上記問題のないターミナル上だと同じに表示される
% cat a
A〜B
C〜D
% cat b
A〜B
C〜D
ところが、Emacsで開くと、ファイル a の"〜”は正しく表示できない
#ref("emacs.png")
何が違うんだろう、、としばらく調べてみたところ、hexdump -C で見ると文字コードが違っていることがわかった。
% hexdump -C a
00000000 41 8f a2 b7 42 0a 43 8f a2 b7 44 0a |A...B.C...D.|
0000000c
% hexdump -C b
00000000 41 a1 c1 42 0a 43 a1 c1 44 0a |A..B.C..D.|
0000000a
これで見ると、ファイル b の "〜" は a1c1 という正しい euc-jp のコードになっているのに対して、
ファイル a の "〜" は、同じ "〜”に見えるものの、8f a2 b7 というコードになっているらしい。
この 8f a2 b7 というシーケンスが、なぜ "〜" になるのかはあれこれ調べてみたけどよく分からない。
8f は JIS X 0211のC1集合のss3(Single Shift 3)かな、と思うが、Shift-JIS でも EUC-JP でも
UTF-8 でも a2 b7 なんてコードは無さげなのだが、Konsoleとかgnome-terminal、Terminalが同じ
結果を示しているのを見ると、何らかのルールは決まってそうな印象
識者の目に触れることを期待して、このあたりに晒しておこう :-)
- cat や nkf だとこんな感じになる
% cat a
A〜B
C〜D
% nkf -e a
A召キB
C召キD
この結果を見る限り、8f a2 b7 というシーケンスは nkf が認識する(= 広く一般に使われている)コードとは違っていて、
それらを素で通したらkonsole等のターミナルが"〜"にしているような印象。ktermでは対応していないようなので、gtk+とか
Qtのレベルなのかなぁ?-- [[kojima]] &new{2010-08-24 (火) 19:43:02};
- こんなpythonのコードで試してみたら、
#! /usr/bin/python
# -*- coding: euc-jp -*-;
import sys
def main():
file = sys.argv[1]
f = open(file, "r")
lines = f.readlines()
for line in lines:
print "before:", line
t = line.decode('euc-jp')
print "after :", t
tt = t.encode('euc-jp').replace("~", "〜")
print "convd :", tt
if ( __name__ == "__main__" ):
main()
Emacs 上ではこういう結果になった。
% ./test.py a
before: A□B
after : A~B
convd : A〜B
before: C□D
after : C~D
convd : C〜D
この結果を見ると、Pythonの世界で 8f a2 b7 というシークエンスを EUC-JP として decode するとUTF的には普通のチルダ(~)
になって、その状態で"~"を"〜"に変換して EUC-JP に encode してやれば本来のコードになるみたい
hexdump で見ても、
% ./test.py a | hexdump -C
00000000 62 65 66 6f 72 65 3a 20 41 8f a2 b7 42 0a 0a 61 |before: A...B..a|
00000010 66 74 65 72 20 3a 20 41 7e 42 0a 0a 63 6f 6e 76 |fter : A~B..conv|
00000020 64 20 3a 20 41 a1 c1 42 0a 0a 62 65 66 6f 72 65 |d : A..B..before|
00000030 3a 20 43 8f a2 b7 44 0a 0a 61 66 74 65 72 20 3a |: C...D..after :|
00000040 20 43 7e 44 0a 0a 63 6f 6e 76 64 20 3a 20 43 a1 | C~D..convd : C.|
00000050 c1 44 0a 0a |.D..|
00000054
ということで、初期状態は 8f a2 b7 が、euc-jp -> UTF8 すると 7e になって、UTF8の世界で s/~/〜/して
euc-jpに戻すと a1 c1 になる、みたい。
とりあえず当初の目的だった 8f a2 b7 というコードを持ったファイル名を修正する方法はメドが立ったけど、
8f a2 b7 というシークエンスがgtk/Qtな世界だとeuc-jpの"〜"に解釈されるのはなぜか、というあたりはよく分からんし、
そもそもWindowsな世界で作ったファイル名がEUC-JPの世界で 8f a2 b7 になる、というのがよく分からんなぁ? -- [[kojima]] &new{2010-08-24 (火) 20:08:47};
- テスト用の python のコード、
tt = t.encode('euc-jp').replace("~", "〜")
としてたけど、これは "〜" が euc-jp な世界なので、そっちに移す余計な処理が入るから、
tt = t.replace("~", u'〜')
の方が正しいか。-- [[kojima]] &new{2010-08-24 (火) 21:59:15};
- wassrの方で教えてもらったけど、8f a2 b7 というのは eucJP-ms というコード体系で FULL WIDTH TILDE を表すもう一つのコードらしい。「もう一つの」というのは、eucJP を名乗っている限り、JIS X 0208ベースの FULL WIDTH TILDEには a1 c1 が割りあててあって、それとは別に JIS X 0212 ベースの FULL WIDTH TILDE に 8f a2 b7 が割りあててある模様。JISの第三水準以降をEUC-JPではどう割りあてるか、というのはあまり調べたことなかったけど、そのあたりに起因する問題だったのか。。 -- [[kojima]] &new{2010-08-24 (火) 23:02:48};
- 毎度あさってな反応ごめんなさいそもそもWindowsでファイル名にチルダを出してしまった時点でボタンを掛け違えているように思います。 -- [[名倉]] &new{2010-08-25 (水) 09:04:20};
- 自由は苦しいんだ、いつも。 -- [[きゅうる村]] &new{2010-08-25 (水) 11:24:19};
- ここで討論するつもりはありません。一言だけ、人間てボタン掛け違うから、そこから調べて学んで成長していけるのではないでしょうか? < しあさっての投稿かも (^^) -- [[M.Tomi]] &new{2010-08-25 (水) 21:47:41};
- 良く分からないけど,これってファイル名だけじゃなくて,ファイルの中身にも関わる問題ですよね? > 文字コードの変換→逆変換で元に戻らない件 -- [[tamu]] &new{2010-08-25 (水) 21:54:12};
- まぁ、UTF-8に行って帰ってくると同じにならない、というのはUnicodeの仕様だから仕方ないだろうけど、8f a2 b7 を〜に見せるのは JIS X0212レベルの話だから、将来的には対応していくことになるんじゃないかな? 手もとでは dolphin や FD が対応できてなかったので、8f a2 b7 を使っているファイルを移動させたりするのが不便だから、必要に応じて調べてみただけ :-) -- [[kojima]] &new{2010-08-25 (水) 22:37:01};
- でも、コマンドラインから操作しようとすると、〜 に見えるのが a1 c1 と 8f a2 b7 の二つある、というのは、見た目は同じでもファイル名は違っている、という困った状況だなぁ。まぁ、Windowsな世界から流れてきた日本語のファイル名のファイルは、とてもコマンドラインで操作する気にはならないので、dolphin/thurnar なGUIなファイルマネージャかFDで操作することになるから、それらで使えるようにファイル名を正規化するのが当面の目的だったので、それはとりあえず解決できたからいいことにしておこう -- [[kojima]] &new{2010-08-25 (水) 22:57:08};
#comment