凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 46600
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

Programming SHOT BAR へようこそ。
最近ちゃっぴ様のエントリで話題に上がった「入力可能な最大byte数を超えた場合のUIはどうあるべきか」という議題について考えて見たいと思います。

通用しなくなった「全角・半角」

かつてShift_JISが日本語の文字コードとして主流だったころ、「全角・半角」という概念は IT業界人ではなくとも知られるほどに浸透しました。今でも携帯電話ではShift_JISが用いられ「全角・半角」という概念が受け継がれています。

この「全角・半角」というものには2つの側面があります。
ひとつは文字のレンダリング幅、もうひとつは文字のbyte数です。

レンダリング幅についてはTrueTypeフォントの普及で等幅ではなくなりました。 1989年にApple社が開発し、Mac OS 7.0から搭載されたようですが、普及したのはWindows95のシステム標準フォントとなった1996年以降ではないでしょうか。普及してからすでに10年以上の年月が経っています。

文字のbyte数についてはShift_JISではいわゆる半角では1byte、いわゆる全角では2byteとなっており、等幅フォントと併用すると見た目の横幅と byte数が一致するという非常に利便性の高い特徴を備えていました。

一変したのはUnicodeの登場以降です。Unicodeの制定は1993年。 1996年にJavaがリリースされましたが、言語の内部コードにUnicodeが採用されました。当時としては非常に先駆的であったと思います。 Java以降のプログラミング言語では内部文字コードにUnicodeを採用しているものが多いですね。
Windows NT4.0ではUnicodeを扱えたようですがWindowsでは1994年にリリースされたWindows NT 3.1からOS内部コードがUnicodeとなりました。しかしWindows 95/98/MEではOSとしてのUnicodeサポートは無く別途ライブラリを用いる必要がありました。 UnicodeベースのOSが一般的なユーザに用いられるようになったのはWindows2000からです。

このUnicode、符号化の際にはUTF-8およびUTF-16が多く用いられていると思いますが、 UTF-8では1byteから4byteまでの可変長コードとなり、日本語の文字は主に3byteになるなど Shift_JISの特徴とはまるで違います。またUTF-8ではASCII文字に関しては1byteで表現され互換性を持っているのに対し、UTF-16ではこれらも2byteで表現されるなど、もはや「全角・半角」時代のbyte数換算は通用しなくなりました。

どのようなUIがよいのか

文字列を入力するUIを考えた場合、ユーザに対して分かりやすい制限は、入力欄のレンダリング幅そのものを入力上限とすることではないでしょうか。先に述べた文字のレンダリング幅側からの制限で対応しようというものです。

画面にしろ、帳票にしろ、表示するには物理的な空間を必要とします。スペースが無いから折り返して表示するなどの手法もありますが、 HTMLなどにみられる可変なレイアウトでの画面の崩れには辟易していませんか?
「入力」という行為はそもそもどこかに「出力」するために行っているわけです。出力する側に都合をつけてもらうのはそれほどおかしな考えではありません。

(Webシステムではやるべきではないですが)出力のフォントが決められており、文字サイズも決まっているのであれば、与えられた空間に入るだけの文字を入力させるUIがユーザにとっては非常に分かりやすい

DBの容量は入力に十分なだけ確保しておくことが望ましいでしょう。 文字のbyte数という側面はユーザにとっては関係のない出来事です。出来るだけ隠蔽したい。ただし、合字などの存在がありますから、スペースに対して非常に多量のbyte数の入力が可能となってしまいます。最大で何byte入力される可能性があるのか推測することは困難です。

そのため、現実的な制限として「レンダリング幅の許す範囲内で、文字数上限XX文字以内での入力が可能」という仕様とする必要があるのではないでしょうか。合字の文字数をばらしてカウントする必要があるという点でユーザへの不便を解消し切れませんが、byte数のカウントが人間にはもはや不可能となった中で人間でもカウント可能な値としたところが最大限の対応です。

DBの容量を気にする方もいると思います。しかし近年、ムーアの法則に追従するように、メモリもストレージも飛躍的に大容量化し、また低価格化しました。 1byteの価値が激減したのですから1byteを削ることに労力を費やすことも割に合わなくなっています。システム要件に見合わなくなるほどのコスト高でしょうか?レコードの見込み件数とbyte数でストレージのコストを算出してみてください。

サロゲートペアへの対応

文字数の問題にはサロゲートペアというものもあるわけですが、これはUTF-16での問題です。
現在のUnicodeは21ビットのコードポイントを持つわけですが、16ビットでは当然ながら表現できません。そこでShif_JISのように2つの文字の組み合わせを使いこの21ビットのコードポイントを16ビット、 32ビットの可変長コードで表現しようというものです。

そのため、本来の21ビットのUnicodeのコードポイントに変換してから処理する分にはなんら問題は発生しません。 UTF-8の場合は7ビットまでのコードポイントは1byteのコード、11ビットまでは2byte、16ビットまでは3byte、 21ビットまでは4byteとなりますから、16ビットを超えるコードポイントを持つ (UTF-16ではサロゲートペアで表現される)文字について4byteで符号化します。
UTF-32での符号化であれば常に4byteでの固定長です。

このあたりはプログラミング上のテクニック的な話題であり、 ユーザに対してサロゲートペアかどうかを意識させてはなりません

合字、合成文字への対応

中様の Unicodeの結合文字は最大何文字くっつけられる?にて紹介されていますが、ハングルやアラビア語、タイ語といった言語の文字や、音符などの記号では複数の文字を合わせてレンダリングするということが行われます。

これらはレンダリング幅では問題ないのですが、byte数を非常に多く消耗します。そして、その入力限界に来た際にどのように警告するのがユーザに分かりやすいか、という話題が残ります。

先にも述べましたが、文字数のカウントはユーザに負担を求めることのできるぎりぎりのラインだと思います。少なくともこれらの文字が「複数の文字の合成だからその文字数分だけカウントしなければならない」というルールをユーザに理解してもらう必要があります。

投稿日時 : 2007年9月13日 14:46
コメント
  • # re: Unicode&TrueType時代の入力制御
    シャノン
    Posted @ 2007/09/13 14:53
    つ[ ZWNBS ]
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/13 15:28
    あー。
    レンダラ側の問題だけかと思ってたけど、文字幅0扱いの文字をどうするかが考察から抜けていますね。
    コピー&ペーストでもない限りは入力時に意図的に入力するんだろうけど、厄介なのは更新処理などの入っていることを意図していないときですね。
  • # re: Unicode&TrueType時代の入力制御
    裏口
    Posted @ 2007/09/13 16:08
    なんか盛り上がってるけど、ついていけない世界。
    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=41182&forum=7
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/13 16:35
    その記事もエントリ書くきっかけのひとつですが、エントリ本文に書いてあることと内容はさほど変わらないですよ。
    昔「全角」と呼んでいた代物はいったい何者だったのか考えろよ、という点に尽きます。

    私はこれを「文字の幅」と「byte数」という2軸で捉えているわけです。
    あとは実際にコードにしたときに具体的にどう対処しようかという話題はあるのですが。
  • # re: Unicode&TrueType時代の入力制御
    ちゃっぴ
    Posted @ 2007/09/13 16:54
    > 先にも述べましたが、文字数のカウントはユーザに負担を求めることのできるぎりぎりのラインだと思います。少なくともこれらの文字が「複数の文字の合成だからその文字数分だけカウントしなければならない」というルールをユーザに理解してもらう必要があります。

    逆にこちらのほうが不可能に思えます。
  • # re: Unicode&TrueType時代の入力制御
    シャノン
    Posted @ 2007/09/13 17:08
    レンダリング幅で制限するってことは、それこそ本当の「倍角文字」を使ったら、入力可能文字数は半分になっちゃうんですかね?
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/13 17:45
    > 逆にこちらのほうが不可能に思えます

    何と比べて不可能といっておられますか?
    「byte数を数えてくれ」が可能で「文字数を数えてくれ」が不可能とは思えません。
    「両方不可能だ」という主張なら理解は出来ます。
    何と比べて「逆に」といっておられますか?

    > レンダリング幅
    倍角なら表示上は倍のスペースを食うわけですから、文字数は減ることになるのが自然なのではないでしょうか。
    帳票にしろ画面にしろ、表示できるスペースは限られますので、その範囲内で書いてくれというシンプルなルールを提示すればよいのではないかと。
  • # re: Unicode&TrueType時代の入力制御
    Jitta
    Posted @ 2007/09/13 22:14
    まけた http://blogs.wankuma.com/jitta/archive/2007/08/20/91162.aspx
  • # re: Unicode&TrueType時代の入力制御
    中博俊
    Posted @ 2007/09/13 23:41
    よく考えると幅の分だけ文字が入るというのは面白い。
    実際の紙幅の範囲でしか文字は書けないわけで、そういう意味ではアナログに近い=人間に理解しやすいでしょう。

    まぁ問題は人間は300ptの文字から1ptの文字まで紙幅に合わせてある程度融通がきくけど、コンピュータみたいに頭の固い奴にはそれが通用しないというところでしょうか;-p
  • # re: Unicode&TrueType時代の入力制御
    渋木宏明(ひどり)
    Posted @ 2007/09/14 0:41
    NT は初代 3.1 の頃から内部 Unicode でしょ?
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/14 9:47
    > Jitta様
    トラックバックありがとうございます。
    あちこち参考にしてたのに投げ損ねてるんで、参考になるところは挙げてくれると助かります。

    >中様
    もともとは私のアイデアではないのですが、どちらにせよ表示幅の制約ってあるものですからね。
    DBでバイト数を指定して容量確保って先入観が強いので最初に聞いたときは「え~?」って思いましたが。
    最近ではユーザビリティ優先ということでこの案がしっくりきます。

    >渋木様
    申し訳ありません。実はNT3.1の頃の実情を知らないので資料伝でしかわからなかったのです。
    NT系にはUnicodeを扱うライブラリが搭載されていたとは聞くのですが、いつのバージョンからどの程度扱えたのかがよく分かりませんでした。
    NT3.1が94年の発売ですから、93年制定のUnicodeを搭載できないことはないですね。
    このあたりの時代のUnicode事情を何かご存知であれば補足願えますか。
  • # re: Unicode&TrueType時代の入力制御
    渋木宏明(ひどり)
    Posted @ 2007/09/14 15:16
    ライブラリとかじゃなくて、OS 内部で使用されている「文字列」が 16bit Unicode です>NT 系

    やっぱり NT3.1 から Unicode 対応みたいですね>NT

    http://support.microsoft.com/kb/99884/ja
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/14 16:05
    なるほど。
    公式の資料が得られて大変参考になりました。
    人によってNT4.0からとか2000からとか諸説あって、しかも検証困難でしたので助かりました。
  • # re: Unicode&TrueType時代の入力制御
    ちゃっぴ
    Posted @ 2007/09/14 23:26
    > 何と比べて不可能といっておられますか?
    > 「byte数を数えてくれ」が可能で「文字数を数えてくれ」が不可能とは思えません。
    > 「両方不可能だ」という主張なら理解は出来ます。
    > 何と比べて「逆に」といっておられますか?

    まず、一口に user といっても仕様を決める人と実際に利用するだけの人とで分れると思います。

    仕様を決定する人は character code に関する仕様を理解している必要がありますが、ただ利用する人はどの文字が結合文字でなんてことを知る必要なんてないと思うのです。
    ぶっちゃけ、結合文字なんてものがあることすら知らなくてもいいと思う。

    私が Bytes を表示したらいいじゃないの?と書いたのはどの文字が何 Bytes 消費しているのか?なんて考させるためではなくて、単に Bytes という制限があってその数値を超えなければ OK という指標を示しているに過ぎません。

    ちゃんと知りたい user はそれを参考に勉強してもらえばいいですし、んなの知ったことか?って user は何も考えず数値が制限を超えない範囲になんども try and error で入力してもらえばいいのです。

    そういう趣旨です。
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/15 1:47
    その趣旨からすると、文字数のカウントが「逆に不可能」という先の発言は取り下げられたということでよろしいでしょうか?

    byte数のカウントは文字ごとにばらした上で、コードポイントが7bit、11bit、16bitの境目で1byte、2byte、3byte、4byteと数えないといけません。
    byte数のカウントは文字ごとにbyteを数える必要がありますから、byte数のカウントをする過程で文字数がカウントできます。コードポイントでの判断の手前で処理を止めればよいのですから。
    しかし逆に文字数のカウントの過程ではbyte数はカウントできません。

    そのことを念頭に置くと、勉強するユーザに限っての参考にする情報としては文字数のほうがbyte数より理解できるユーザが多いということから、ユーザの負担をより減らすという意図で文字数の制限とするほうが妥当言うことになります。
    byte数制限の場合は文字数をカウントする以上の負担をユーザに負わせるわけですから。

    これが、先の私の
    「『byte数を数えてくれ』が可能で『文字数を数えてくれ』が不可能とは思えません。
    『両方不可能だ』という主張なら理解は出来ます。」
    の論拠です。

    本文中の「ぎりぎりのライン」というのはぎりぎりセーフ、もしくはぎりぎりアウトかなという意図でした。
    勉強するユーザに負わせるにはかろうじて可能と私は考えていますが、NGじゃないの?と判断する人もいることでしょう。
  • # re: Unicode&TrueType時代の入力制御
    中博俊
    Posted @ 2007/09/15 19:29
    >byte数のカウントは文字ごとにばらした上で、コードポイントが7bit、11bit、16bitの境目で1byte、2byte、3byte、4byteと数えないといけません。

    ん?
    UTF-8の話になってない?
    基本UTF-16の話だと思ってるんだけど。
  • # re: Unicode&TrueType時代の入力制御
    凪瀬
    Posted @ 2007/09/15 21:53
    >UTF-8の話になってない?
    おわ。失礼しました。
    なんとなく自分の中でUTF-8だと思っていました。

    UTF-16の場合はbyte数のカウントで文字ごとにサロゲートペアかどうかを判定する必要がありますね。

    UTF-32であれば文字数とbyte数は一致するわけですが、
    いずれにせよ、byte数の計算は文字数の計算よりも大変という主張でした。
  • # re: Unicode&TrueType時代の入力制御
    ちゃっぴ
    Posted @ 2007/09/17 1:44
    > その趣旨からすると、文字数のカウントが「逆に不可能」という先の発言は取り下げられたということでよろしいでしょうか?

    "逆に" というのはおっしゃるとおりおかしいですね。

    わからない人にとっては、どちらも意識しなくて結構。
    示された数値より大きければ NG という logic だけ
    知ってもらえればいいと思います。

    詳しい user および勉強したいと思っている user は
    そこに示された数値を基に勉強していってもらえば
    いいんじゃないか?というのが主旨になりますので。
タイトル
名前
Url
コメント