WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:jcode.plでの文字化け。

0:[投稿] j [2004/12/15 16:03 ][環境:ie6 linux perl5.8 apache2]

あるファイル(sjis)をjcode.plで変換すると特定の文字で文字化けしてしまいます。

ですが、試しにapache経由で<input>タグからその文字を入れて送ってファイルに落とすと正常に表示されます。
これは何故なのでしょうか?

ちなみにその文字は "ア" という文字です。

jcodeでもちゃんと変換できるようにはならないものでしょうか?


1:[回答] andi [2004/12/15 18:10 ]

具体的にどのようにコーディングして上手く行かないのでしょうか?

> jcode.plで変換すると

変換先の文字コードは何でしょうか?

> あるファイル(sjis)

公開できるファイルですか?

> <input>タグからその文字を入れて

入れた文字は「あるファイル」と全て同じですか?
それともその文字化けする文字だけを入れたのですか?

またフォームから入力された文字列はサーバ側で
受け取った時点でもsjisだったのでしょうか?


取り合えずファイルに「山崎良」と入れてみて
ファイルオープン→変換して新しいファイルに書き込み
でeucに変換して問題無く変換されました。

jcodeのバージョンはv 2.13.1.5です。


2:[回答] B-Cus [2004/12/15 18:52 ]

> 取り合えずファイルに「山崎良」と入れてみて

機種依存文字な方の崎 (立ち崎) ではないかと。

ちなみに立ち崎は 89区のものと 116区のものがあります。
http://www2d.biglobe.ne.jp/~msyk/charcode/kisyuizon/msgotic.html


3:[回答] j [2004/12/15 20:02 ]

>>1
すいません。説明不足でした。
sjis -> euc の変換の時に化けてしまいます。jcode.plのバージョンは2.13です。

あと、その化ける文字というのは"崎"ではなく"ア"です。

>>2
ありがとうございます。やっぱり機種依存文字ですか。
89区と116区というのがあるんですね。
nkfでもkccでもやっぱり化けてしまうのですが、<input>からapache通してURLエンコーディングを戻すとちゃんと"ア"となるのです。
昨日からだいぶ格闘してましてEncode::from_toでもやっぱり化けてしまうのです。
どうにか方法は無いでしょうか?


4:[回答] AC1号 [2004/12/15 20:17 ]

ダンプするとFA B1だったので、116区のIBM拡張文字のようです。
jcode.plはJIS X0201, X0208, X0212とASCIIをサポートするとマニュアルに書かれていますので、IBM拡張文字はサポート外の文字です。というより、そもそもFA B1はShift_JISの外字領域なので、これがIBM拡張文字である保証が全くありません。

perl5.8を使っているのであれば、Encode.pmを使った方がよいかと。
http://digit.que.ne.jp/work/index.cgi?Encode
http://digit.que.ne.jp/work/index.cgi?Perl5.8.0JP
Windowsでしか使わないというのであれば、cp932を使うという方法もあります。
(ネットで使う場合はcp932を使うのは危険だが)


5:[回答] AC1号 [2004/12/15 22:10 ]

X0208, X0212を見てみましたが、立ち崎はありません。つまり、euc-jpでは「存在しない文字」ということになります。euc-jpではあきらめるしかないですね。


6:[回答] B-Cus [2004/12/16 00:21 ]

あとは &#64017; とか。


7:[回答] B-Cus [2004/12/16 00:48 ]

あと、JIS 的には 94区までが有効なので、EUC-JP や ISO-2022-JP
も 94区までならマッピングする領域自体は存在します。なので、もし
 - ブラウザとは Shift_JIS でやりとり
 - ファイルには EUC-JP として保存
という状況であれば、89区の立ち崎なら EUC-JP っぽいエンコーディング
として格納することは可能なような気がしなくもないです。

ただし Microsoft 的には NEC 選定 IBM 拡張文字はできるだけ
使わず、IBM 拡張文字に寄せる方針なので、それとは反すること
になります。

あと、試してないので嘘かも。


8:[回答] j [2004/12/16 01:25 ]

>>4, >>5
ありがとうございます。あまりコアなところは分からないので恥ずかしながら
正直な所書いてある内容が理解できません。勉強したいと思います。

上のほうでも書いた通りie->apache経由の場合にはちゃんと"ア"が出る(Tera Tarm上で)
のでそれを調べてみました。

unpackで"C*"としたところ、249,245,10と配列が返ってきたので逆に
print pack("CCC", 249, 245, 10); としたところちゃんと"ア"が出てきました。

これはどう理解すればよいのでしょうか?


>>7
ありがとうございます。
pack("CCC", 249, 245, 10); で出てくる文字が89区という事なのでしょうか?


9:[回答] j [2004/12/16 01:32 ]

追記です。

上記内容ですがコンソールからkonしてから見てみると化けてました。
ちゃんと出るように見えたのはwinからtera tarmで見たからですね。

訂正します。"ちゃんと"出てくると書いたのは間違いでした。


10:[関連] 古のもの [2004/12/16 01:39 ]

この記事、最初 cygwin の w3m で見たら
> ちなみにその文字は "ア" という文字です。
と見えて、“ア”なんて化けるのかー
と思って FireFox で見たら、あらビックリ。
ちなみに FireFox で文字列をコピーして
Meadow (Windows 版 Emacs) にペーストしたら謎のコード+半角のアに化けた。
w3m で“ア”に化けたのはこれのせいか?
きっと Emacs w3 で見ても化けるんだろうなぁ……。

まぁ、JIS にない以上 Shift_JIS で表現しようが
化けるクライアント環境はあるさね。


11:[回答] B-Cus [2004/12/16 02:04 ]

> print pack("CCC", 249, 245, 10); としたところちゃんと"ア"が出てきました。
249, 245, 10 は 0xF5 0xF9 0x0A で、0x0A は改行コードなので
0xF5F9 が立ち崎として表示されているということです。

これが >>7 で書いた、無理矢理 EUC-JP っぽいエンコーディングで
立ち崎を表現することもできる、という実例です。

このケースでは

 1.SJIS 立ち崎
  ↓(Apache)
 2.EUC-JP っぽいエンコーディングの立ち崎
  ↓(TeraTerm)
 3.SJIS 立ち崎

の 1 と 3 でしか立ち崎が表示されず、
> 上記内容ですがコンソールからkonしてから見てみると化けてました。
となるわけです。

念押ししておきますが、規格的には EUC-JP に 0xF5F9 という文字は
存在しません。

で、結局どうするかですけど、
> あるファイル(sjis)をjcode.plで変換すると特定の文字で文字化けしてしまいます。
jcode.pl で変換して最終的に何がしたいのか、元ファイルを
修正してはダメなのか (立ち崎→普通の崎、とか)、などを提示
した方がよいかと。


12:[回答] j [2004/12/16 09:01 ]

>>10
w3mですか。そこまでは試してなかったのですね。
今あるブラウザはIEとネスケの4.78と7.1(共にwin)しかなくて。確かに機種依存文字(?)だから
見えたり見えなかったりするんでしょうね。
winには有るからwin環境なら一応映るということで。

>>11
0x0A(10)はLFですね。恥ずかしい(>_<)。気付きませんでした。
私のほうで最終的に何がしたいかというと、

sjisのファイル(固定長)から30項目ぐらいのデータを取得してmysqlに格納
してそれをwebから参照するというものです。

文字化けを発見したら手作業で元ファイルを変更するということは可能ですが、数千
以上のファイルがあるためなかなか文字化けを目で確認するのは難しいです。

立ち崎→普通の崎 などの変換が自動に出来るのであれば便利です。ただ、全ての文字化け
を把握するのは難しいと思いますが可能なのでしょうか?

とりあえずunix上は化けても見るクライアントはwinなのでそこで化けなければ構わないの
ですが。

sjisでそのまま保存するのがベストなのでしょうがsjisだとまた別のトラブルがありそう
なのでlinuxでの保存時にはeucでやりたいと考えています。


13:[回答] B-Cus [2004/12/16 09:28 ]

> 立ち崎→普通の崎 などの変換が自動に出来るのであれば便利です。ただ、
> 全ての文字化けを把握するのは難しいと思いますが可能なのでしょうか?

 http://www2d.biglobe.ne.jp/~msyk/charcode/kisyuizon/msgotic.html
で機種依存文字のコード範囲はわかるので、
 http://www2s.biglobe.ne.jp/~cru/library/junk/depwin.pl
のように正規表現で事前にチェックすることは可能で、この例では
丸付数字やギリシャ数字以外は全部ゲタに変換しています。

しかし、立ち崎→普通の崎 という変換をしたいなら、変換先の
文字を調べるのは確かに面倒です (その手間を惜しまないなら、
>>6 のように文字参照に変えてしまう方がよいかも)。


あるいは URL エンコードしたり BLOB などの形式で Shift_JIS のまま
mysql に突っ込む方法もあるかもしれません。

もし該当項目を SQL で検索したいという要望があるなら
 - jcode.pl で EUC-JP に変換したものを検索用項目に格納
 - Shift_JIS な元データを BLOB な表示用項目に格納
という二本立ても考えられますね。

ただ、なるべく初期の段階で機種依存文字を排除する方針の方が
何かと後々楽できることは確かです。


14:[回答] j [2004/12/16 10:46 ]

ありがとうございます。教えていただいたdepwin.plはソース見て勉強します。

とりあえず私なりの回避方法を思いつきました。
jcode.pl(2.13)の554行目(or 556行目)のところに以下を入れてどうなるか観察してみようと思います。

if($c1 > 255 || $c2 > 255){ return "○"; }

これはperlを-wで動かしたときに
---------
Character in "C" format wrapped at jcode.pl line 554, <FILE> line 1.
---------
というmsgが出る場合に文字化けするのを見てjcodeソースからとりあえずこんな感じにしてみました。
とりあえず今のところ問題ない感じに見えます(見えるだけなんでしょうけど)。


15:[回答] j [2004/12/16 10:49 ]

追記:
とりあえず↑で化けるのは回避できるかなと。
`echo '***' | nkf -Se`とかだと化ける文字が消えてしまいますから上の方法だと○で気付くことはできるかなと思いまして。


16:[回答] AC1号 [2004/12/16 20:54 ]

・Windowsで表示できればよい
・立ち崎以外にもいわゆる機種依存文字が出てくる可能性がある
であれば、内部コードはutf-8を使い、Encode.pmを使って
cp932→utf8・utf8→cp932の変換を行うのがよいのではないでしょうか。
cp932はIBM拡張文字などを含むshift_jis(もどき)を扱えます。
#私は使ったことがないので保証はできません


17:[回答] j [2004/12/17 09:34 ]

そうですね。utf8が使えればベストなんですが。
使えなくも無いですけど、OSやDBなど文字コードを統一する形で
行いたいと思っていますので当分eucの予定です。

来週あたりfedora試すのでmysql4.1と一緒に検討する予定です。


18:[回答] AC1号 [2004/12/19 12:15 ]

B-Cusさんや私が言う通り、euc-jpには立ち崎はなく、euc-jpで立ち崎を表現することはできません。

困難であることを承知でeuc-jpを使いたいのであれば、cp932にあってeuc-jpにない字はエスケープする方法があります。
いわゆる機種依存文字の範囲は >>13 で提示されているのでその範囲の文字をjcode.plなどで*変換する前*にエスケープしてから

\自体→\\
立ち崎(0xFAB1)→\FAB1

そして出力時はeuc-jp→shift_jisへの変換後に

\FAB1→立ち崎(0xFAB1)
\\→\

という変換を行います。

ちなみに、jcode.pl自体を変更するのは好ましくありません。jcode.plは今では時代遅れなものであるとはいっても、メンテナンスは行われています。jcode.plのupdateの度にjcode.plの変更作業が発生します。


19:[回答] j [2004/12/19 23:02 ]

そうですね。euc-jpに無い以上しょうがないのですが、ブラウザから
EUCエンコードしてapache経由でjcode変換したコードをeucのまま出力
するとブラウザできちんと立ち崎が表示されます。

euc-jpには存在しなくてもブラウザでwin上で表示(Tera Tarmでも)すれ
ば "表現できる" 方法があります。

そのため上のほうで機種依存文字全部を知る方法を教えていただいたので
コツコツ変換表を作ろうかと考えています(まだ取り掛かってませんが)。

私の場合、サーバへ取り込み時にeucに変換したあとは再度sjis等への変換
は考えていないので教えていただいた方法は使えません。


>>6のように &#64017; というのも検討してみましたがこれに伴う変更が
莫大なので断念しました。


20:[回答] AC1号 [2004/12/22 07:05 ]

>>11のようなやり方でうまく行くのは偶然にすぎません。たまたまsjis・euc相互間の変換の実装がIEとTeraTermで同じであっただけで、将来updateがあってもうまく行く保証はありません。そういうわけで立ち崎を含む文字セット(cp932やUTF-8)を使うことや、エスケープを薦めているわけです。

&#64017; の64017は、ucs2で立ち崎を表したときの10進数でのコードポイントなので、機種依存文字の部分だけEncode.pmでcp932→ucs2という変換を行えば、変換表を作らずともできます。


21:[回答] j [2004/12/22 15:43 ]

>>20
そうですか(*_*)。偶然ですか。

utf8を使用しようと思いテストし始めたのですが、まったくうまくいきません。

"ア"という文字だけを入れたファイルをsjisで作り、単純に

---------------------------------
(test.pl)
#!/usr/bin/perl -w
use utf8;
use Encode;

open(FILE, "<:encoding(shift_jis)", "test.txt"); # <- "ア"と書いてあるファイル
print &Encode::encode("utf8", <FILE>), "\n";     # <- 出力。
---------------------------------

としたのですが、
shiftjis "\xFA" does not map to Unicode at ./test.pl line 6.

となってしまいます。"あいうえお"なんて文字だとちゃんと変換されるので、
"ア"(0xFA, 0xB1 : 116区)の場合、utf8でもやっぱりダメなんでしょうか?


22:[回答] AC1号 [2004/12/22 22:30 ]

shiftjisではなくcp932を使って下さい。

shift_jisの厳密な定義は、JIS X 0201とX 0208からなる文字符号化方式で、問題となっているIBM拡張文字などは含まれていません。文字が存在しない所を何かに変換しようとしたので"shiftjis "\xFA" does not map to Unicode"と怒られるのです。
cp932はshift_jisにIBM拡張文字などを追加したものです。jさんがsjisと言っているのはshift_jisではなく、本当はcp932なのです。


23:[回答] j [2004/12/22 22:48 ]

ご指摘ありがとうございます。まったく理解できてなかったですね...恥ずかしい(>_<)

sjisの元ファイルは私が作ったものではなく別のところから取得してくる(送ってもらう)
ものなので変更ができません。

と、いうことは utf8 にしようと euc にしようと無理ということですね(*_*)。

http://www.atmarkit.co.jp/aig/01xml/shiftjis.html

↑を先ほど読みました。各社が独自にいろいろやっているとの事なのでシフトJISの
文字コード変換というのは課題が多いようですね。
私の場合、99.9%ぐらいはちゃんと変換できていて残りの0.1%のためにめちゃくちゃ難儀してます^^b

業務で使用したり企業システムなんかだとこういうのは結構シビアだと思うんですけど
一体どのように回避してるんでしょうね?


24:[回答] B-Cus [2004/12/22 23:07 ]

> open(FILE, "<:encoding(shift_jis)", "test.txt");
open(FILE, "<:encoding(cp932)", "test.txt");

ということでしょう。こちらの環境ではうまくいきました。

perldoc Encode::JP にも
 cp932 : Code Page 932 = Shift JIS + MS/IBM vendor mappings
とあります。


25:[回答] j [2004/12/23 01:25 ]

ありがとうございます。それでできました。

perlは何年か使ってましたが、正直な話 use Encode; は先週初めて知ったぐらいの
知識しかないので試行錯誤の状態です。
encoding(***)にcp932というので指定ができたのですね。

unicodeも初めてなので Tera Tarm で表示するときに化けない方法もよく分からなく困ってます^^b
無いのかな? nkf -Be でも化けるのがあるし難しいですね。

やっぱりこれからの世界はutf8ですね。これから勉強して本格的に移行しようと思います。


26:[回答] j [2004/12/23 10:30 ]

↑の"nkf -Be"の所は無視してください^^b。寝ぼけてたようで...。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World