文字コードの最近のブログ記事

Java 9では国際化機構で用いられるリソース文字列のファイル表現の文字コードとしてUTF-8がデフォルトで使用されることになるそうです。従来、ISO/IEC 8859-1がデフォルトであるためにUnicodeエスケープが必要となり、外部ツールで日本語テキストを「\u3042」のようなエスケープ文字列に変換する煩わしさがありましたが、ようやく解消されることになります。

Javaには古くから国際化のための枠組みが用意されています。その最も基本的な機構となる、多言語のメッセージ文字列を用意する仕組みとしては設定ファイルなどに用いるプロパティファイルという形式が用いられています。ところがこのファイルはデフォルトの文字コードがISO/IEC 8859-1という西欧向けの1バイトコードなのでした。

このため、JDKではnative2asciiというツールが提供されて、Shift_JISやEUC-JP等の文字コードからUnicodeエスケープを用いる形式に変換できるようにされていました。また統合開発環境のEclipseにはプロパティエディタというプラグインが開発され、コマンド操作なしにあたかも直接漢字を記述できるかのような操作が可能になっています。とはいえリソースファイル自体はもちろんUnicodeエスケープなので、普通のテキストエディタで表示すると欧文以外は全く読めないものになります。

Javaのプロパティファイル自体はUTF-8で記述されても読み込めるように既になっていたのですが、その重要な用途である国際化のリソースファイルとして読み込むResourceBundleクラスではなぜかISO/IEC 8859-1がデフォルトという状態が長く続いていました。実は自分でクラスを定義して一工夫してやるとUTF-8にできるという裏技(?)もあったりしたのですが、そういうのはデフォルトで提供してほしいものです。(この辺のことは拙著『プログラマのための文字コード技術入門』第7章に記しています)

オープンソースのWebアプリケーションフレームワークであるPlay Frameworkではリソースファイルにわざわざ別の仕組みを用意してUTF-8で直に書けるようにしています。リソースファイルがもっと早くUTF-8で符号化できるようになっていたらこのような措置はとられれなかったかもしれません。

遅きに失した感はあれども、ともかく改善されることになって良かったです。

Unicode 10.0が2017年6月20日にリリースされました。今回は8,518文字が追加されています。

日本語話者にとって最も関係しそうなのは変体仮名の導入でしょう。

変体仮名とは

現在、平仮名は1音につき1文字ですが、以前は同じ音に対して複数の書き方がありました。例えば、平仮名の「か」は漢字「加」が元になっているもので、これ以外に「か」と読む平仮名はありませんが、かつては「可」を元にした仮名も使われていて同じく「か」と読まれました。そうした複数のバリエーションがあった仮名を明治時代に標準化したものが今の平仮名です。このとき採用されなかった異体が変体仮名と呼ばれるものです。

変体仮名は今日では文章を綴るのには使われませんが、そば屋の看板などで装飾的に用いられることがあります。

Unicodeにおける変体仮名

変体仮名はUnicodeではBMPでなく面01に配置されました。U+1B000-1B0FFのKana SupplementブロックおよびU+1B100-1B12Fの Kana Extended-Aです。例えば先ほど例に挙げた「可」に基づいた「か」は符号位置U+1B019にあり、文字名はHENTAIGANA LETTER KA-3とされています。読みを「KA」のように示して、複数ある異体は数字で区別されています。全部で285文字の変体仮名が収録されています。

符号化の方式としては、単純にひとつの符号位置にひとつの文字が対応する形になっています。複数の読まれ方をする字がありますが(例えば「惡」に基づく字、「あ/を」)、こうしたものもひとつの符号位置にのみ置かれ、読みが違うからといって重複して配置されてはいません。標準化の途中の段階では、音価に相当する符号位置を与えて異体字セレクタのようなもので変種を示すといった案もあったようですが、最終的には扱いやすい形式に落ち着いたことになります。

漢字の追加も

今回、CJK統合漢字拡張Fが追加されています。7,473文字と結構大きな追加です。使う機会があるかどうかはまた別の話ですが......。

拡張Fのコード範囲は2CEB0-2EBE0となっています。

Pythonとlibiconv, nkf, Javaのコード変換を比較した記事がありました。

ASCIIとJIS X 0201の違いに起因する円記号問題とチルダ・オーバーライン問題、それにUnicodeのFTPサイトが原因と思われる全角ダッシュの件という既知の問題が多いので目新しくないのですが (『プログラマのための文字コード技術入門』をお読みいただければわかります)、Pythonについて目新しげな話がありました。

Pythonでは他と違って、二重(白抜き)の括弧をU+FFxxの位置にあるものでなくU+29xxに割り当てているそうです。うむ。そうか、そうきたか。

JISの公式な対応表ではU+FFxxの方になっています。文字名でいうとFULLWIDTH {LEFT|RIGHT} WHITE PARENTHESISです。

ただ、ここで「なぜFULLWIDTHなのか」という疑問を持った方もいるでしょう。本来UnicodeのFULLWIDTH/HALFWIDTH云々というのは、シフトJISのように1バイトコードと2バイトコードとの間で重複符号化のある符号化方式との往復変換の救済用に設けられたものです。ところがこの括弧記号はJIS側の符号化方式(Shift_JISやEUC)で重複符号化されているものではないので、本来FULLWIDTHになるきちんとした理由はありません。にもかかわらず、UnicodeにJIS X 0213の文字を追加する作業でなぜかFULLWIDTHの方に入れてしまいました。

一般に用いられている変換表は、(多少ヘンだと思ったかもしれないにせよ)このUnicodeの作業を反映したものになっています。JIS X 0213の追補1でもそうなっています。Pythonのような判断をしたものは私はほかに見たことがありません。

Pythonがこうしたのは、強い信念のもとでの判断なのか、そうでなく何か行きがかり上そうなっただけなのか、ちょっと興味を惹かれるところではあります。

UnicodeにはのちにU+2E28, 2E29に{LEFT|RIGHT} DOUBLE PARENTHESISというのが追加されて(バージョン5.1らしい)、どうもこっちがいいんじゃないかという気もしてくるのですが、後から出してこられるのはつらい。3.2の時にあれば良かったのですが。

ちなみにこの二重の括弧は、文章や辞書において文中に入れる注記の類に用いられることのある記号です。

【追記 2017年6月7日】 JISとUnicodeの間のコード変換表はこちらから入手できます。JISの公式な定義と同等です: JIS X 0213のコード対応表

北海道南部の松前町は、20世紀日本の書家・金子鷗亭の出身地であり、その影響で書道教育の盛んな町として知られています。

その松前で高校生の書道パフォーマンスの大会が開催されたニュースがありました。

上記のうち、函館新聞の方は記事の中にちょっと残念な部分があります。書家の名前が「金子鷗亭」と、「鷗」の字がHTMLの文字参照になってしまっています。40407は16進表記で9DD7にあたります。UnicodeでU+9DD7は第3水準漢字「鷗」の符号位置です。

人手で40407のような数字を入力したとは考えにくい。私の想像ですが、テキストエディタなどで「鷗亭」と入力したあとで、工程上の何らかの段階でシフトJISに変換することがあったのではないでしょうか。その際に、第3第4水準漢字まで対応しているJIS X 0213Shift_JIS-2004ではなく、第1第2水準までしか対応していないJIS X 0208ベースのShift_JIS (ないしはその誤った実装であるCP932) に変換しようとして、このような結果になったのではないか。

SJISとの変換が必要な時には、Shift_JIS-2004 ないしは Shift_JISX0213 を指定すれば、こうした問題は起きなくなります。Python, PHP, Java, libiconv等を用いるとUTF-8とShift_JIS-2004との間でコード変換ができます。

この鷗(かもめ)という字は、常用漢字には入っていませんが、人名用漢字には入っています。文化的な分野ではこの金子鷗亭や森鷗外といった人名に使われますし、白鷗大学 (栃木県) という大学名や鷗島 (北海道江差町) といった地名にもあります。いつでも使えるように、第3第4水準漢字に対応した符号化方式 (第3第4水準文字コード) を常に用いることが肝心です。

なお、上記ニュース記事のもう片方、毎日新聞の方では、「鴎」という略字体を使っています。これはJIS X 0208の1983年改正で大きく字体の変えられたものとして有名ですが、元は新聞による使用の方が83JISよりも先だったのだそうです。その意味では、新聞がこの略字を使うのは一貫していると言えなくもない。ただ、表外字の部分字体にも略字体を適用しようとするなら鴎の一字だけでなく全ての表外字が対象になるのか、そうでないのなら鷗が適用対象になる理由は何なのかと、方針がなかなか難しくなってくるので、元来の字体 (鷗) にあわせるのが無難であろうと思います。

GNU libiconvはJIS X 0213の符号化方式、Shift_JIS-2004 (Shift_JISX0213) や EUC-JIS-2004 (EUC-JISX0213) に対応していますが、コマンドを実行した際にこれらが入っていない場合もあり得ます。入っているかどうかはiconvのコマンドラインオプション --list で確かめられます。

これらの符号化方式に対応するには、ビルドする際にconfigureのオプション --enable-extra-encodings を指定しておく必要があるようです。インストールされているiconvコマンドでShift_JIS-2004が使えないときはこれが指定されていなかった可能性があります。もしこれらの符号化方式が入ってなかったら、管理者に相談するか、そうでなければ、自分でソースをダウンロードして上記のオプションを用いてビルドしてみるのもいいでしょう。

SJISやEUCと変換するときは常にShift_JIS-2004, EUC-JIS-2004を使いたいので、これらに対応した iconv コマンドを用意しておきたいものです。

参考: GNU libiconv

「2バイト文字」という言い方につっこみをしている人をあるところで見かけたので、これについて少々。

漢字や平仮名を「2バイト文字」のようにいう語法はずっと前からあります。昔からあるのだからいいのかというと、むしろこれは昔だからこそ便宜的に通用した言い方で、今では不適当です。順を追って説明します。

「何バイト」は文字そのものの性質ではない

まず、根本的なこととして、ある1文字の符号化表現に何バイトを要するかは、文字それ自体の属性ではなく、用いる文字コード (コード系) に依存することです。

例えば片仮名の「ア」を符号化するのに必要なバイト数は、JIS X 0201なら1バイト、JIS X 0213なら2バイト、UTF-8なら3バイト、UTF-32なら4バイトと様々に異なります。割り算の記号「÷」は、ISO/IEC 8859-1では1バイト、JIS X 0213では2バイト、UTF-32なら4バイト。

昔はあまり気にしなくてよかった

ただ、昔はそういう面倒なことを言わずに済んだのは、日本ではASCII/JIS X 0201とJIS X 0208だけを考えていれば良かったためです。これなら「漢字は2バイト文字」のような言い方で良かった。1バイトコードと2バイトコードを混在させると英数字や片仮名に1バイトと2バイトの両方が出てきますが、前者を「半角」後者を「全角」と呼ぶことであたかも別の文字のような扱いをすることで乗り切ってきた。

そういう牧歌的な時代が過ぎて、Unicodeが出てきたりまた8859など他の文字コードも意識するようになると、「どの文字コードの話をしているのか」をはっきりさせないと「何バイト」ということはいえなくなったわけです。

特定のコード系についての話ならOK

もっとも、逆に言えば、例えばShift_JIS-2004といった特定のコード系を前提とした場面では、「2バイト文字」とか「1バイト片仮名」といった言い方は全然アリです。

まとめ

  • 漢字や平仮名といった (コード系とは独立な) 文字種のつもりで「2バイト文字」というのは不適当。ある文字が何バイトかは用いるコード系による。
  • 特定のコード系を前提とした場面で、その系における1バイト文字、2バイト文字、のような言い方はOK。
  • なぜ昔はそういう煩わしいことを気にせずに済んだかというと、ASCII/JIS X 0201とJIS X 0208しか対象としていなかったから

関連記事

すごい後知恵なんですが、1980年代に「EUC」方式の文字コードをISOで国際標準化しておけば良かったのではと考えます。

EUC方式、というのがどういうことかというと、

  • 8ビット符号表のGL領域(0x20-0x7F)にASCIIを配置、
  • GR領域には2バイトの漢字コードを配置

という形が基本で、必要に応じてシングルシフトコードでG2, G3に指示されている2バイト(ないし1バイト)符号化文字集合をGRに呼び出せるステートレスな符号、というものです。

具体的には、EUC-JIS-2004, EUC-JP, EUC-KR, EUC-CNなどです。

これはISO/IEC 2022の枠内の運用なので、別段この方式を改めて標準化する必要はないのではないか、という意見もあるでしょう。しかし、型決めしておくことによるメリットもあります。理解が容易になり、設計や実装も使い回せる。特に2022は複雑ですからね。

ISO/IEC 8859という規格は、GLにASCII、GRに欧州等の各地域ごとの文字集合を配置した1バイトコード、という形になっています。この2バイト版があっても良かったのではないか。

それは世の中で「EUC」と呼ばれてそれなりに共有されているのだけども、ISOで標準化されていなかったのはもしかすると惜しかったのではないか。特に、2バイトコードが出てきた早いうちからそれがあれば......、と考えた次第です。

日経新聞のサイトに気になる題の記事が載っていました。

私は飲むとすぐ赤くなる方なので読んでみたのですが、異なる方面で発見がありました。通常JIS第3水準漢字で表記される単語が使われていたのです。

酒皶という言葉

記事の途中に、「鼻や頬の一部が飲んでいないときでも赤くなる症状を「酒さ」(しゅさ) と呼ぶ」とあります。この記事では平仮名にしていますが、漢字では「酒皶」と書きます。この「皶」という漢字はJIS第3水準、面区点番号1-88-70です。

なぜそんなことを知っているかというと、以前にも見覚えがあるからです。ブログ記事にもしています。

この記事では、『皮膚の医学 肌荒れからアトピー性皮膚炎まで』 (田上八朗著、中公新書) という本に出てきたのを取り上げていました。

この言葉は国語辞典の大辞林や広辞苑にも出てきます。第3水準漢字を使った「酒皶」という漢字表記も載っています。ちなみに広辞苑はこの酒皶という症状について「酒客に多いが飲酒と無関係にもおこる」としています。

病気や医学といった分野にも第3第4水準漢字は時々現れるのです。

文字入力とコード変換

この酒皶という単語は、Emacsで動作する文字入力プログラムSKKの第3第4水準辞書に入っていますから、SKKでは辞書ファイルとしてSKK-JISYO.JIS3_4を参照していれば、何も特別な操作なしに「しゅさ」という読みから変換できます。

文字コードとしてはUTF-8やShift_JIS-2004, EUC-JIS-2004などで扱えます。JIS X 0208ベースのShift_JISなどでは符号化できないので、SJISにコード変換する場合は下記のようにiconvコマンドでShift_JIS-2004 (Shift_JISX0213) を指定すれば文字化けせずにうまくいきます。

  iconv -f UTF-8 -t SHIFT_JISX0213 < utf8.txt > sjis.txt

書家・金子鷗亭の作品の特別展が北海道立函館美術館で開催されるとのニュースがありました。

金子鷗亭とは

金子鷗亭は1906年生まれ、2001年没で、函館から比較的近い松前町の出身です。1990年に文化勲章を受章しています。漢文に偏ったそれまでの書のあり方を批判し、生活に近い口語文や短歌などを題材とすることを提唱、漢字・平仮名・片仮名の調和を重視したということです。日本酒「一ノ蔵」のラベルでも知られます。

鷗という字と文字コード

この「鷗」はJIS第3水準、面区点位置1-94-69にあります。鳥のカモメの意味です。音読みではオウと読みます。

PCでかもめと打って変換すると「鴎」の方が先に出てくることが多いでしょう。こちらはJIS第1水準、1-18-10です。

JIS X 0208はもともと、18-10の位置に「鷗」がありました。しかし1983年改正で「鴎」という略字体に変更されてしまいました。これは表外字なので常用漢字体ではありません。新聞の紙面では、独自に略したこの字体が採用されていたそうです。JIS X 0208の拡張版であるJIS X 0213で、元の字体が第3水準漢字として1-94-69に復活しました。

このニュース記事では注釈として「文字化けを回避するため「かもめ」の人名用漢字を鴎に置き換えました」と記しています。「「かもめ」の人名用漢字」というのは間違いとも言いにくいですがちょっと微妙な説明です。確かに「鷗」は人名用漢字に入っていますが、この説明だと「普通のカモメの漢字のほかに「人名用漢字のカモメ」という特殊な漢字がある」かのような理解をしてしまう人がいそうです。そうでなく、元来「かもめ」の漢字は「鷗」なのであり、この字は常用漢字表には入っていないが子の名付けに使って良い字に含まれている、というのが実際のところです。一方、「鴎」は新聞などで使われた「鷗」の略字体で、83JIS変更によってPCではこっちの字体しか出ない状態が長く続いたので広まっているものです。

このような面倒な説明を避けるためには記事で「鷗」を使えばいいわけですが、このニュースサイトはJIS X 0208ベースの Shift_JIS を使っているので「鷗」は表現できません。JIS X 0213ベースに拡張した Shift_JIS-2004 や、Unicodeの UTF-8を使えば問題なく表現できます。その際、単にHTMLだけでなく、記事の執筆・編集・管理といった作業工程全体で第3第4水準文字コードを用いることが必要です。

例えば、作業工程のあるフェーズで、UTF-8にて作成したファイルをSJISに変換する必要があるなら、Shift_JIS-2004を指定すれば良いです。これなら、「鷗」のような第3第4水準漢字や、非漢字たとえば著作権表示記号やユーロ記号なども文字化けしません。iconvコマンドではこうします:

  iconv -f UTF-8 -t SHIFT_JISX0213 < utf8.txt > sjis.txt

逆向きの変換、つまりSJISからUTF-8に変換するには、-f と -t を入れ替えてやります。これはCP932の波ダッシュ問題も引き起こさず、最も正当な変換結果が得られます。

  iconv -f SHIFT_JISX0213 -t UTF-8 < sjis.txt > utf-8.txt

余談ながら

冒頭の展覧会は道立函館美術館で12月11日まで開催とのことです。この美術館、函館の観光名所・五稜郭のすぐそばにあります。新幹線も開業したことですし、旅行の一環として行くのにも向いているでしょう。

下の画像は年末、雪の時期の五稜郭の写真です。12月11日だとまだ雪は積もっていないかもしれませんね。函館美術館はこの五稜郭を上から眺める五稜郭タワーの近くにあります。

台湾語を使った結婚会見

リオ五輪でも活躍した卓球の福原愛選手の結婚会見についての記事が目を引きました。

台湾の江宏傑選手と結婚したことから日本だけなく台湾でも会見が行われました。そこで福原選手の話した言葉を取り上げたものです。

福原選手は以前から中国で卓球のトレーニングをしてきたので中国語(標準語、いわゆる北京語)に堪能だとのことです。台湾でも大陸から来た政権のもとで標準語たる北京語が普及していますが、一方、現地の言葉として台湾語というのがある。これは台湾の対岸に位置する福建省で話される閩南語が元になっています。北京語とは大きく異なるものだそうです。

福原選手は台湾の会見では台湾語で挨拶して現地の人々から好評を得たそうです。

台湾の言語事情についての書籍

台湾語の事情については、以前、本の紹介の形で当ブログの記事に書いたことがあります。

ここで紹介した本、『初めて台湾語をパソコンに喋らせた男—母語を蘇らせる物語』は、思ったより複雑な台湾の言語事情を含め大変興味深く面白かったので、気になる方は是非読んでみてください。

第3水準漢字の必要性

冒頭のニュース記事では台湾語のルーツについて「ビン南語」と記されていました。「閩南語」の「閩」がJIS X 0208の第1・第2水準にない漢字なのでこういう表記になったのでしょう。この字はJIS X 0213の第3水準、面区点1-93-49にあります。JIS X 0213の第3・第4水準漢字が使える環境なら、問題なく漢字で入力できます。

SKKの第3第4水準辞書を使うと「びんなん」という読みから「閩南」に変換できます。Macの辞書にも入っています。

このようなことからも、JIS X 0208でなくJIS X 0213を用いることの重要性が分かります。SJISとUTF-8の間のコード変換では、iconvで "SHIFT_JIS" の代わりに "SHIFT_JISX0213" を指定すれば、この「閩南」も問題なく変換できます。常にこのやり方を用いることをおすすめします。

最近のブログ記事

『アイヌと縄文』の第4水準漢字:「埦」
瀬川拓郎『アイヌと縄文: もうひとつの日…
札幌で見たJIS X 0213の文字
札幌の中心部、大通公園と札幌駅を地下でつ…
Pokémon GO の JIS X 0213の文字
その字はJISにある スマホゲームのPo…
函館の花火大会の第3水準漢字
花火大会の記事にJIS第3水準漢字があっ…
Unicode Standardの元号の説明の問題は変わっていなかった
生前譲位の報道でUnicode仕様書の元…

広告