LoginSignup

Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

123
63

「住所は英数字もすべて全角で入力してください」はなぜそうなったのか

Last updated at Posted at 2024-08-03

Webサービスのフォームに住所を入力するとき、丁目や番地などを入れる欄について、数字やハイフンを全角で書かなければいけない「全角縛り」をやっているフォームをよく見ます。半角文字を入力してしまってエラーになったり、咄嗟に変換方法を思い出せなかったり、全角と半角の見分けが付きづらかったり、「全角縛り」であることが明示されていなかったり、「ハイフン」としてどの文字を使うべきかわからなかったり……と、鬱陶しさを感じることが多くあります。

これについて「そもそも何故そういう仕様が生まれたのかわからないな」と思ってTwitter1に書いてみたところ、いろいろな反響がありました。そこでいろいろ知らなかったことを学べたり、それがキッカケでいろいろ調べたりしたので、その内容をまとめます。

筆者の考えについて

先に、筆者の立場を明確にしておきます。私は、現在稼動しているものに関しては、どんなアプリケーションであっても住所の欄について「全角縛り」をするべきではない、そもそも不必要に文字種の制限をするべきではないと考えています

いまどき、ユーザーはパソコンからも、スマートフォンからも、Webサービスをはじめとするアプリケーションを利用します。ハードウェア、OS、日本語入力システム、表示に使われるフォントなど、多様な環境で使われます。しかも同じ人がいろんな端末を使っていたり、気軽に買い替えたりもします。

PCなら半角・全角の切り替え方がわかるがスマートフォンではわからないとか、この端末では半角と全角が見分けづらいとか、新しく買った端末やインストールしてみた日本語入力ソフトではわからないとか、同僚や家族にやり方を聞かれたが端末のOSが違うのでわからないとか、そういうことが起こりやすくなっています。

ユーザーも多様になっています。昔ならパソコンの入門書や授業や研修で全角文字・半角文字といった概念を学んできたユーザーばかりだったかもしれません。今はそういう決まった入口でないところからも老若男女がITを使いはじめています。あるいは、日本語にあまり馴染みのない海外出身のユーザは、彼らの言語圏にはない全角文字・半角文字についてよくわからないということもありそうです。
全角文字・半角文字といった概念を必ずしもユーザーが習得しているわけではありません。

UTF-8(やShift_JISやEUC-JP)では、半角文字から全角文字へのプログラム上での変換は非常に簡単です。もし全角文字で保存しなければならない都合があったとしても、ユーザーが入力した文字を全角に変換してから保存してしまえばいいのです。

「全角縛り」は、様々な技術的・コスト的制約があり、ユーザーの端末の種類もITへのリテラシーの高さもある程度限定されている中で、当時の開発者なりの最適解だったのかもしれません。当時の状況での選択に関して悪く言うつもりはありません。しかし今となっては、時代遅れで、無くしていくべきものだと私は思います。

特定の文字種別が必要であれば自動的に変換をするなどをして、システムの都合でユーザーに不便を押し付けることがないようにしたい、あるいはしてもらいたいものです。

そういうことを言っていく、改善を働きかけていくためにも「なぜ全角が良いとされているのか」「なぜ今までその仕様が残りつづけているのか」を知ることには意味があると思っています。そういうつもりで、いろいろと調べたりしていました。

印刷のため説

最初になるほどと思ったのが、印刷のレイアウトが計算しやすいから、という話です。窓付き封筒のような限られた文字数しか表示できない場所に印字するとき、全角に統一することで改行位置の調整がやりやすくなるというのです。ほかにも、印刷や表示まわりのいろいろな経験談や、「こうではないか」という推測を見かけました。

  • 原稿用紙や方眼紙に印刷をしたい
  • ぴったり収まるような改行位置を推測しやすい
  • 縦書き印刷すると半角英数字が横向きにされてしまう

私も文字列がレンダリングされた時の幅や高さ、改行位置、特定の幅にぴったり収まる文字数を計算したいという状況に頭を悩ませたことが何度もあります。いわゆる全角文字に限定されていれば、「半角文字2つで全角文字1つぶん」のような計算やレイアウトをしなくて済みます。

JIS X 0208 だから説

何人かが指摘していたのが「JIS X 0201とJIS X 0208が独立した規格だから」というものでした。

アメリカの国内規格としてのASCIIコード、国際規格としてのISO/IEC 646を元に、日本語を扱うためのカタカナなどの文字を追加した規格がJIS X 02012でした。ASCIIコードと重複する部分のなかでは、バックスラッシュが円記号に、チルダがオーバーライン記号に変更されています。

ASCIIコードはすべての文字が7ビットの範囲に収まりますが、JIS X 0201ではカタカナを扱うため7ビットの範囲には収まらず、1文字を8ビットで表現するか、7ビットでは制御文字を使ってラテン文字の集合とカタカナの文字集合を切り替えるようになっているようです3

カタカナ以外の、より広い文字を定義した文字集合の定義がJIS X 0208です。JIS X 0208は、1文字が7ビットまたは8ビットを1バイトとして2バイトぶんの情報量を持ち、数字・ラテン文字・ひらがな・カタカナ・漢字・ギリシャ文字・キリル文字など幅広い文字が含まれます。

JIS X 0208の定義する文字集合を、実際のビット列にする符号化方式は複数あり、そのなかにはJIS X 0201の使用する領域と被ってしまうものがありました。文字の符号化では、7ビットまたは8ビットで表現できる 0x00 から 0xFF (7ビットの場合は 0x00 から 0x7F)の範囲がCL、GL、CR、GR領域と呼ばれます。

  • CL領域: 0x00 から 0x1F
  • GL領域: 0x21 から 0x7E
  • CR領域: 0x80 から 0x9F
  • GR領域: 0xA1 から 0xFE

上記には 0x20 0x7F 0xA0 0xFF が抜けています。0x200x7F はASCIIコードで SPACEDELETE に割り当てられていた場所で、JIS X 0208のどの符号化方式でも同じく SPACEDELETE が割り当てられています。 0xA00xFF は、8ビットでの 0x200x7F の先頭ビットの値を 1 にした値です。

ASCIIコードでは、GL領域にすべての文字が入っています。また、JIS X 0201の8ビット表現では、カタカナがGR領域に配置されています。ASCIIコードでは、CL領域に制御文字が入っていました。JISではJIS X 0211に制御文字が定義され、C0集合と呼ばれる制御コードはASCIIと同じでCL領域に、8ビットの場合はC1集合と呼ばれる制御コードがCR領域に割り当てられる場合があります。

つまり、CL領域と、C1集合の制御文字を使う場合はCR領域をよけて、おもにGL領域とGR領域を文字集合に割り当てていくことになります。そのため、GL領域を使えばASCIIコードの文字と、GR領域を使えばJIS X 0201のカタカナと競合してしまいます。JIS X 0208に定義されている符号化方式で、文字集合を素直にマッピングしたような構成の「漢字用7ビット符号」や「漢字用8ビット符号」はGL領域を使い、ASCIIやJIS X 0201の文字と共存できません。

のちにインターネットの時代には、EUC-JPやShift_JISのようにJIS X 0201とJIS X 0208を混在させられる符号化方式が普及して、当たり前に両方の文字を使えるようになりました。EUC-JPはJIS X 0208の文字の表現にGR領域を使用し、JIS X 0201のカタカナは1バイト目を 0x8E にした2バイトコードになっています。Shift_JISは第一バイトにCR領域とJIS X 0201が使用していない部分を、第二バイトではCL領域や 0x7Fを除いた部分を使って、共存できるようにしています。これらの符号化方式は、後からJIS X 0208に符号化方式として追加されています4

このとき、JIS X 0208由来の文字がいわゆる「全角文字」、JIS X 0201由来の文字がいわゆる「半角文字」となりました。さらにそれがすべての言語の文字を扱おうとするUnicode文字集合や、その符号化方式であるUTF-8にも引き継がれ、今に至ります。

そんななか、JIS X 0201と混在できないJIS X 0208の符号化形式を使用しているシステムとデータを共有したり、その時代のデータ形式を継承していたり、あるいはバックエンドそこから接続されたどこかでそういったシステムが現役で動いていたりして、「全角縛り」が発生してしまっているというのです。

制御文字を挟みたくなかった説

JIS X 0208とJIS X 0201のように文字集合が複数あったり、7ビットでJIS X 0201を使用する場合などは、限られたビット数のなかで複数の文字集合を切り替えて使う必要があります。そこで、制御文字をはさんで文字集合を切り替えながら文字列にしていくという符号化方式が考案されました。

たとえば7ビットでJIS X 0201を使用する場合には、 0x0E (SHIFT IN)より後ろの文字はカタカナ、0x0F (SHIFT OUT) よりも後ろの文字はラテン文字、という切り替え方をしていたようです。

制御文字を挟む方式で、日本で最も普及していそうなのがISO-2022-JPで、長いこと電子メールで使用されるエンコードとして親しまれてきました。ISO-2022-JPでは、0x1B (ESC) から始まるエスケープシーケンスを挟むことで文字集合を切り替えています。このエスケープシーケンスは3バイトあり、半角と全角を切り替えるたび3バイト消費してしまうのを避けたかったので「全角縛り」をしているのではないか、というのです。

また、専門外で調べきれていませんが、こういった制御文字を使用した文字種別の指定はメインフレームでも採用していることが多いようです。メインフレームではEBCDICという、ASCIIとは全く由来を別とする文字コード体系が採用されており、ベンダーごとに日本語化拡張を開発した歴史があるようです。Wikipediaの漢字シフトコードのページには、ISO-2022-JPのほか、ベンダー独自の漢字シフトコードも紹介されています。

制御文字によって文字集合を切り替える方式は、制御文字のせいで見た目よりも長いバイト列を使ってしまう以外にも、部分文字列を切り出したり文字数をカウントしたりするときにも考慮が必要そうで、システム設計時には文字種をなるべく混ぜたくない気持ちになりそうです。

COBOLが原因説

これもまた専門外ではあるのですが、原因としてCOBOLがあるのでは、と指摘する人も多くいました。COBOLではしばしば固定長のレコードが使われ、またデータ型の定義の時点で2バイトコードに固定されてしまうらしいのです。

具体的には、PICTURE (PIC) 句によってデータ型を宣言する際、N を使用すると「国別項目」や「日本語項目」と呼ばれるデータとなり、これが2バイト固定だというのです。これらは日立製作所やIBMのドキュメントで確認できます。

こういった場所には、いわゆる半角英数字のような1バイト文字を含む文字列を保存できず、住所のように漢字・ひらがな・カタカナと数字が混在するデータに対しては「全角縛り」をするしかない、というのです。

関係なさそうな説

ほかにもいろいろな説が寄せられましたが、おそらく関係ない、または大きな要因ではないだろうと思ったものもありました。

SQLインジェクションを防ぐため説

「SQLインジェクション対策ではないか」という人がそれなりの数いました。が、これは私は無関係、もしくは関係があったとしても「ついで」程度のもので関連性は薄いと思っています。

SQLインジェクションは、SQLベースのデータベースを利用しているサービスに対し、SQL文がシステムの意図通りに動かず、別のデータを書き換えたり読み込んだりしてしまうのを狙う攻撃手法です。SQLインジェクションは大抵、記号文字のエスケープ漏れを狙うはずです。それらは半角文字が使われるので「全角縛り」がSQLインジェクション対策になるということのようです。

たしかに「全角縛り」をしているフィールドではSQLインジェクション攻撃は成立しないでしょう。しかし、もしSQLインジェクション対策として「全角縛り」をしているとしたら、すべての入力欄で「全角縛り」をしなければなりません。そんなことは現実的に可能でしょうか……?

すべての入力欄で「全角縛り」をするということは、ユーザーが担当者への要望を記載したり、配送時の置き配指示をしたりする自由入力欄も全角で書かなければいけないということです。これは住所の「全角」縛りよりもさらに鬱陶しいはずです。メールアドレスやURLも全角で書かなければいけなくなるかもしれません。全角に直されたメールアドレスやURLは、もはやそれはメールアドレスやURLと言えるものではないでしょう5

「SQLインジェクション対策」という名前のもとに「全角縛り」をやる前に、もっと本質的な対策をする必要があるはずです。

とはいえ、本質的な対策が漏れていた箇所がたまたま「全角縛り」だったおかげで被害が起きずに済んでいるというケースはあるかもしれません。あるいは、「全角縛り」のされている箇所にはSQLインジェクションやXSSを発生させる文字列を入れる方法がないため、脆弱性診断やQAテストの工数を減らせている効果はあるかもしれません。そういう意味で「ついで」程度の関係はあるかもしれない、とは思っています。

検索・突合・ソートのため説

「入力された住所を検索したり、他のデータと突き合わせたりするために全角に絞っているのではないか」という意見もありました。しかしこれも、あまり関係がないと思っています。

日本の住所データは表記ゆれが非常に起きやすい性質があります。「全角縛り」をやっていようがいまいが、表記ゆれが起きてしまいます。たとえば、丁目・番地・号が「1-2-3」の住所を書くにしても、

  • 1-2-3
  • 1の2の3
  • 1丁目2番地3
  • 1丁目2-3
  • 一丁目二番地三

のように、いろいろな書き方ができてしまいます。漢数字とアラビア数字を混ぜたりすると組み合わせはもっと増えます。「全角縛り」をやったところで、表記ゆれの激しいデータが生まれてしまうのです。検索・突合・ソートを行うのであれば、まずこの表記ゆれを解消するところからやらなければなりません。その難しさは半角英数字が紛れ込んだところでそんなに変わらないように思えます。

もうひとつ気になるのは、「そもそも住所を、丁目・番地・号のレベルで検索する需要はそんなに存在するのか?」というところです。

住所の「全角縛り」をやっているのは会員登録フォームだったり荷物の配送先の指定フォームだったりするわけで、おそらく顧客データや注文データと紐付けて管理することになるでしょう。では、顧客データや注文データを、住所で検索するニーズはあるのでしょうか?「特定の地域へ営業をかけるため、○○県の顧客リストが必要」とか「配送ドライバーに、××市の注文データの配達を依頼する」のように、都道府県や市区町村、もしかしたら町名くらいのレベルで検索するニーズが生まれたり、そういう業務フローが組まれていることは考えられます。しかし丁目・番地・号のレベルの検索というのはどうもピンと来ないのです。そういうことができる状況では、おそらく他の情報も手元にあって、他の情報をキーにして検索したほうがよさそうに思うのです。

  1. Xという名前が気にいらないので、いまだに「Twitter」とか「ツイート」と呼んでいます。

  2. 策定当初はJIS C 6220でしたが、のちに現在使われている規格番号に変更されています。ややこしいのでこの記事では現在使われている規格番号に統一します。

  3. 「1バイトは8ビット」が正式に定義されたのは2008年のIEC 80000-13で、特に昔のコンピューターの世界は6ビットだったり7ビットだったりが混在していたので、今回紹介しているJIS規格でも7ビットの処理系が考慮されている、という話も今回の本筋とはあんまり関係がないですが、注釈くらいは必要かもしれません

  4. ただしEUC-JPは、JIS X 0201のカタカナやJIS X 0212の補助漢字など、JIS X 0208に存在しない文字を抜いた状態でJIS X 0208に追加されています

  5. 新聞社や通信社がWebに載せるニュースでのURLの記載方法について、その中の方々にはぜひ考えてみてほしい問題でもあります。

123
63
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
Linked from these articles

Comments

StoneRiver
@StoneRiver

●全角で入力してください。
→システム側で全角に変換しろよと思う。
●カタカナで入力してください。
→「ひらがなorカタカナで入力してください。」にして、システム側で変換しろよと思う。
●ハイフンなしの郵便番号を入力してください。
→システム側でハイフン取れよと思う。
●半角で入力してください。
→以下略

2
@fugahogeds

変換をかますようにサーバーサイドで実装すると「変換ミスで意図しないものが起きる可能性」とか言い出す輩が現れるので、最初から「一切の変換を行わない」という意図のもとで文字の制約をかけたのかもしれないとか思いました。

根拠としては弱いですが、銀行で昔半角カタカナで入力させていたのもそのあたりが絡まないかなと思った次第。

1
StoneRiver
@StoneRiver

変換をかますようにサーバーサイドで実装すると「変換ミスで意図しないものが起きる可能性」とか言い出す輩が現れるので、最初から「一切の変換を行わない」という意図のもとで文字の制約をかけたのかもしれないとか思いました。

Excelの計算結果を電卓で再計算しないと気が済まない系統の方々ですね。

できない言い訳を言い出したらきりがなく、そういった方々に改善を阻害された経験は私自身、多々あるので、おっしゃりたいことはわかります。
ただ、それは各現場の問題であり、設計思想とはまた別ものかなと思う次第です。

変換をかますようにサーバーサイドで実装すると

フロントエンドのチェック処理に組み込むことを私は想定しています。
(リアルタイムでのチェックや変換ではなく、確定ボタンなどを押下した際の動作に組み込むことを想定)

不安があるのであれば、確定ボタンを押下した後の確認画面などで自動変換した個所に警告文を表示するなどで自動変換している個所の確認を促すような仕組みにすることも可能だと思います。

根拠としては弱いですが、銀行で昔半角カタカナで入力させていたのもそのあたりが絡まないかなと思った次第。

今でもバックエンドではCOBOLなどの古いシステムが稼働している場合があるので、その辺を考慮しているケースがあるであろうことは、私も想定しています。
また、そうでなくとも、全角半角やハイフン有無など、ある程度データの形式を統一しておきたいという考えは理解できます。(むしろそういった考えに賛同します。)

それを、ユーザーの入力にゆだねるのではなく、ある程度フロントエンドで補助するのは、システムの使用感の向上につながると思います。

自動変換を行うことで、極一部には、めちゃくちゃないちゃもんをつけてくるユーザーがいる可能性も否定できませんが、そういった輩のために多くのユーザーの利便性を犠牲にはしたくないところです。

2
@UziDeer

半角 => 全角
とかは全然できるかもしれないけど、
全角 => 半角
が全然簡単にできないのがつらいところですよね

0
StoneRiver
@StoneRiver

全角 => 半角
が全然簡単にできないのがつらいところですよね

変換対象を英数字、ハイフンなどの記号に絞って考えれば、さほど難しいことではないのでは?
できる範囲で自動変換し、変換後に全角文字が残っている場合は、チェック処理でエラーにすればよいと思います。

0
ymrl
@ymrl

銀行で昔半角カタカナで入力させていた

これはおそらく全銀協(全国銀行協会)のフォーマットが、JIS X 0201またはEBCDICの、1文字1バイトのカタカナと大文字アルファベットを使用文字としているのが由来だと思います。なので、住所の「全角縛り」とは関係なさそうです。

1
StoneRiver
@StoneRiver
(Edited)

銀行で昔半角カタカナで入力させていた

古くは、1レコード当たりのバイト数を削減したい(レコード長を短くしたい)というのが理由だったと思います。WEBシステムが台頭すると、半角カタカナは文字コードの相違によって文字化けが生じる場合があったので、逆にWEB系のシステムでは半角カタカナが避けられるようになったと思います。

なので、住所の「全角縛り」とは関係なさそうです。

メインフレーム系のシステムでは、全角半角混在があまり一般的ではなく、全角文字を扱う場合はシフトコードで囲む必要があるので、全角半角が混在している項目は扱いにくい。
古いシステムが生きている場合は、そういった理由もあるかもしれませんね。もしくは、そのころの考え方が慣習として踏襲されているだけなのかもしれません。企業によってそれぞれだとは思いますが。

0
@jinno_keisuke(じんじん)

全てを半角で記載することはできなくとも、全てを全角で記載することは可能。
従い、記載全部に亘って全角か半角かを統一させ、処理を単純にするには全部を全角で入力させるのが合理的。

0

Let's comment your feelings that are more than good

Being held Article posting campaign

paiza×Qiita記事投稿キャンペーン「プログラミング問題をやってみて書いたコードを投稿しよう!」

~
View details
123
63

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address