http://tanaka.sakura.ad.jp ウェブアプリで文字コードを簡単かつ確実に判別する方法 - さくらインターネット創業日記

ウェブアプリで文字コードを簡単かつ確実に判別する方法

| コメント(0) | トラックバック(0)

最近、某とあるサイトにて文字化けが起こるという申告が増えてきました。
理由は2つあって、ひとつは携帯(AU)からのアクセスが増えてきたということ、もうひとつは海外からの利用が増えてきたことです。
いちおう明示的にUTF-8と指定しているのですが、AUさんはShift-JISで送ってきたり、中国語のよく分からないクライアントはGB2312で送ってきたりして、文字判別は一筋縄にはいきません。
今回は、文字化けを防ぐ改造に当たってやったことを書きたいと思います。

文字化けの話はGoogleででも検索を

さて文字コードを自動判別するという技術は色々あって、よく利用されるのは特定の文字コードでしか利用されない文字を探し当て、判別するというものです。
言わずと知れた漢字コード変換コマンドである nkf でも、上記の方法で非常に精度の高い自動判別を行ってくれます。
ただ、これには大きな問題があります。それは「短い文字列だと判別できない」ということです。
某とあるサイトでは、単語を入力してロゴを作るというウェブサービスを提供していますが、入力される文字列が短いことからうまく自動判別がうまくいきません。

そのため今回取った対策は、submitされるフォームデータと共に判別用文字列を送るというものです。
例えば「文字」という文字列をUTF-8で送ると%E6%96%87%E5%AD%97となり、Shift-JISで送ると%95%B6%8E%9Aとなります。
ですので、判別用文字列がどのような文字列になって送られてきたかを見ると、他のフォームデータの文字コードを知ることが出来るというわけです。

それでは実際のプログラムです。
detectstrのところが、判別用文字列を埋め込んだところです。
ちなみに「文字」というのを利用した理由ですが、日本語のみならず、中国語簡体字、中国語繁体字においても同じ形だからということです。例えば自動という文字の場合は、簡体字で動という文字が異なるコードになってしまいますので利用できません。
なお最初は「日本」という文字を判別用文字列にしていたのですが、hiddenで日本という文字列が入っていると中国の利用者の方からいらぬ誤解を受けたり都市伝説化するのも嫌なので、途中で変えました。

送信側プログラム

<form action="test.php">
<input type="hidden" name="detectstr" value="文字" />
名前: <input type="text" name="name" />
<input type="submit" value="送信" />
</form>

受信側プログラム

<?php
$charsetList = array(
  "utf-8"  => "%E6%96%87%E5%AD%97",
  "sjis"   => "%95%B6%8E%9A",
  "euc-jp" => "%CA%B8%BB%FA",
  "jis"    => "%1B%24BJ8%3Bz%1B%28B",
  "Big-5"  => "%A4%E5%A6r",
  "HZ"     => "%7E%7BNDWV%7E%7D",
  "EUC-KR" => "%D9%FE%ED%AE",
  "GB2312" => "%CE%C4%D7%D6",
);
$charset = NULL;
foreach( $charsetList as $key => $val ){
  if( @$_GET["detectstr"] == $val ){
    $charset = $key;
    break;
  }
}
if( !$charset ) die("Couldn't detect a character set");
$name = mb_convert_encoding( @$_GET["name"], "UTF-8", $charset );

print htmlspecialchars($name);


なお、「文字」以外を判別用文字列に利用したい方の為に、コードジェネレータを作りました。


以上、いかがでしたでしょうか。
少々セコいですが、簡単かつ確実に行える対策です。
ただ、フォームの送信元と送信先の両方のプログラムに手を入れることになりますので、それが出来ない環境では別の方法をとる必要がありますのでご注意を。

トラックバック(0)

トラックバックURL: http://tanaka.sakura.ad.jp/mt/mt-tb.cgi/1018

コメントする

自己紹介

本名:田中邦裕/1978年生まれ
1996年にさくらインターネットを創業しホスティングサービスを開始。 98年に有限会社インフォレスト(2000年に解散)設立後、翌年にさくらインターネット株式会社を設立して社長に就任。
05年に東証マザーズに上場
kunihirotanakaをフォローしましょう

このブログ記事について

このページは、田中邦裕が2010年12月15日 13:35に書いたブログ記事です。

ひとつ前のブログ記事は「ddコマンド実行途中に、何バイトコピーできたかを見る方法」です。

次のブログ記事は「無料の携帯ソーシャルゲームが成り立つ訳」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 6.0.6