• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:UTF-8とASCIIコードにおける互換性について)

UTF-8とASCIIコードの互換性について

このQ&Aのポイント
  • UTF-8とASCIIはそのASCIIコードの範囲のおいて互換性を持っています。
  • ただし、UTF-8で符号化される際にはUnicode上のコードポイントの値に復元されるため、互換性がなくなることがあります。
  • 具体的には、UTF-8で符号化した際のバイト列には上位バイトが付加されるため、ASCIIと一致しないUnicodeコードポイントが得られることがあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.9

No1,3,6です。 >とあった時、おそらくどの言語でもそうだと思うのですが、スクリプトファイル内の特定の文字列はそれぞれ個別にエンコーディング情報を持つと思います。(※言語によっては持たいない?) 持たないのが普通です。 文字列個別にエンコード情報を持つのは、メジャーな言語だとRubyくらい? 他の言語では、プログラム中では1つのプログラム中では一種類のエンコードしか扱えません。もしくは、言語は全くエンコードを関知せず、すべてプログラマが管理するか。 最初の疑問に戻って、 「UTF-8とASCIIはそのASCIIコードの範囲において互換性を持ちます。」 というのは、 「ASCIIコードの範囲の文字を、ASCIIでエンコードしても、UTF-8でエンコードしても、全く同じ値になる」という意味であり、それ以上でも以下でも無いです。 別の言い方をすると、ASCIIコードの範囲の文字しか含まれないファイルであれば、そのファイルのエンコードがASCIIだとかUTF-8だとか、さらに(バックすらスラッシュ等)一部の記号を除けばSHIFT_JISだとかeuc-jpだとかいうのも区別できないというか同じです。

すると、全ての回答が全文表示されます。

その他の回答 (8)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.8

元々の疑問である互換性については、このように見てみたら分かりますか? (A) ASCIIで書かれたテキストファイルを、UTF-8として読み込む場合 テキストファイルの中の'A'(0x41)はUTF-8でも同様に'A'に対応するので、問題は発生しません。 たとえばコンピュータの内部表現としてUTF-16を使っている場合は、ファイルを読み込んだ後に1バイトの0x41→2バイトの0x0041に内部的に変換された上で処理が実行されるでしょう。その際、元のファイルで'A'を表していた文字は内部表現でもやはり'A'を表すものとして処理されます。そういう意味で互換性があります。 (B) UTF-8で書かれたテキストファイルを、ASCIIしか理解しないソフトウェアで読み込む場合 ASCIIに含まれる文字だけがそのテキストファイルに書かれているのであれば、ASCIIしか理解しないソフトウェアで読み込んでも問題は発生せず、互換性があります。 一方、UTF-16で"ABC"と書かれたテキストファイルを同じソフトウェアで読み込んだら、余計な0x00のバイトが入るために"ABC"という文字列だと解釈してもらえず、つまり互換性がありません。 漢字などを含むUTF-8のテキストファイルを同じソフトウェアで読み込んだら当然問題が発生しますが、「ASCIIに含まれないコードを読み込んだらその部分を無視する」という作りになっていれば、最低限ASCIIの範囲で書かれた部分だけは元の内容のとおりに読み込んで処理できます。

1000vicki
質問者

補足

>その際、元のファイルで'A'を表していた文字は内部表現でも >やはり'A'を表すものとして処理されます。そういう意味で互換性があります。 なるほど、符号化した値がASCIIとUTF-8で同じだから相互変換ができるというだけでなく ASCIIの0x41 と UTF-16における0x0041も同じAを指すように文字コード上でも定義しているというプログラム的な互換性だけでなく、仕様上の互換性も兼用しているという意ですか。 その点は頭から抜け落ちていました。 なるほど。すこし疑問が氷解しました。

すると、全ての回答が全文表示されます。
回答No.7

> (※これが気になってますが、符号化されたバイト列を再度文字集合の文字に > 戻す場合の表現・いいまわしって復号化というような言い方をするのでしょうか > ?) 「符号化文字集合」とその元になった「文字集合」は一対一で対応します。 なので,厳密に取り扱う場合を除くと,「符号化文字集合」は「文字集合」と同一視しています。 さて,厳密に取り扱った場合ですが, 「文字集合」の各文字に対して『値を与える』行為を『符号化』と呼んでいます。 なので,「符号化文字集合」の各々の値は,文字そのものを指します。 「符号化文字集合」→「文字集合」の対応付けを辿る行為を表現するなら, 『値に対応付いた文字』 とか 『値にある文字』 とかになると思います。 > このhoge(0x0041)っていう変数をpack()やGetString()などを用いてASCIIコードとして > Aという文字に復元することはできないけれども、 UTF-16は「エンコーディング」です。 UTF-16という「エンコーディング」をUS-ASCIIという「符号化文字集合」を用いて利用するのであれば, 0x0041はUS-ASCIIの4/1の文字,つまりはAを意味します。 > ASCIIの場合、ASCII文字集合上のコードポイントと符号化した際のバイト値は同一なのですね。 同一です。 > 特定の文字列はそれぞれ個別にエンコーディング情報を持つと思います。(※言語によっては持たいない?) 内部表現としてエンコーディング情報を持つ物はあると思います。 あくまで内部表現であって,文字列の必須情報ではありません。 処理上,その表現が必要だから持っている,というものです。 本質的に,文字はエンコーディング情報を持つ物ではありません。 「あ」は「あ」だし,「A」は「A」です。 あくまで(符号化されていない)「文字集合」に属します。 コンピューターで取り扱うためには番号を振らないといけないので,「符号化文字集合」ができ, その振られた番号をどう取り扱うかを決めないとコンピューターで使えないので「エンコーディング」ができています。 > UTF-8のアスキー範囲内の文字はUS-ASCIIと同じ符号化を行なっているという UTF-8自体は,既存のシステムで動作することを念頭に作られたところがあります。 システムの大多数は,少なくともコマンドはUS-ASCIIの範囲で受け付けるため, そのシステムを障害無く動かせる,という作りになっています。 # EUC-JPなども似た発想があります。あれはISO 2022に則った作りではありますが。

すると、全ての回答が全文表示されます。
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.6

No1,3です。 No3の補足について。 「文字→文字コード」の変換をunpack、その逆をpackと表現しているのであれば、その通りです。

1000vicki
質問者

補足

このひとつ前の回答の内容ですが >英字の A を、0x41 というコードで表現すると言う意味でUS-ASCIIもUTF-8も同じです。 これはたとえば CGIの類をUTF-8で書いた時、明確にいうと#coding: utf-8 と明示してスクリプトファイルを書いた時 そのファイル内で変数なりリテラルなりで記述したアスキーコード内の文字に関しては hoge = "A" とあった時、おそらくどの言語でもそうだと思うのですが、スクリプトファイル内の 特定の文字列はそれぞれ個別にエンコーディング情報を持つと思います。(※言語によっては持たいない?) hogeUtf8 = hoge #utf-8という文字コード情報をもつリテラル hogeAscii = hoge. toAsciiFromUtf8() #メソッドは架空です。 とした場合 hogeUtf8はUTF-8 hogeAsciiはUS-ASCII と異なる文字コードだけども、 こ両変数は スクリプトファイルがASCIIでかかれていても、UTF-8でかかれていても 動作する。 これを実現するために UTF-8のアスキー範囲内の文字はUS-ASCIIと同じ符号化を行なっているという 解釈でおk?

すると、全ての回答が全文表示されます。
回答No.5

えーっと,「符号化文字集合」と「エンコーディング」の関係がわかっていないのでしょう。 # 規格によって言葉が色々異なるのですが……。 まず,「文字集合」が存在します。 Unicodeなどの他に,常用漢字表なども「文字集合」です。 数値が振られていないため,コンピューターで取り扱う上では「文字集合」は現実的には使われませんが。 そして,「文字集合」に数値を振った物が「符号化文字集合」です。 Unicode, JIS X 0208やUS-ASCIIは「符号化文字集合」です。 Unicodeのコードポイントとは,この「符号化文字集合」に振られた数値のことになります。 JIS X 0208では区点値です。 「エンコーディング」は「符号化文字集合」をどのようにコンピューター上で取り扱うか,という取り決めです。 UTF-16, UTF-8,Shift_JISやUS-ASCIIは「エンコーディング」です。 US-ASCIIは「符号化文字集合」であり「エンコーディング」でもあります。 で,「符号化文字集合」にISO/IEC 10646-1 (≒Unicode) で,「エンコーディング」はShift_JISということもよくあります。 # HTML 4.01のShift_JIS文書など。HTML 4.01は文字集合がISO/IEC 10646-1と規定されています。 > UTF-8とASCIIはそのASCIIコードの範囲のおいて互換性を持ちます。 というのは,「エンコーディング」の取り決めの話です。 Unicodeが文字集合である場合,U+0000 - U+007Fの範囲はUS-ASCII/UTF-8ともに0x00 - 0x7Fに符号化されます。

1000vicki
質問者

補足

別の方の回答補足にも書いたのですが、 >Unicodeが文字集合である場合,U+0000 - U+007Fの範囲は >US-ASCII/UTF-8ともに0x00 - 0x7Fに符号化されます。 これは hoge ="A"とあった場合 UTF-16だった場合 0x0041と符号化されますね? このhoge(0x0041)っていう変数をpack()やGetString()などを用いてASCIIコードとして Aという文字に復元 (※これが気になってますが、符号化されたバイト列を再度文字集合の文字に 戻す場合の表現・いいまわしって復号化というような言い方をするのでしょうか ?) することはできないけれども、 hoge = "A" これが、UTF-8の場合、 0x41となって これは ASCIIコードにおける【A】という文字を符号化した値と同一だから コンピューター的にはこの0x41がもともとASCIIの文字を符号化したものなのか それともUTF-8から符号化されたものなのかという点問題ではないということですかね? ※>US-ASCIIは「符号化文字集合」であり「エンコーディング」でもあります。 どうやら見落としていたのはここだったようです。 ASCIIの場合、ASCII文字集合上のコードポイントと符号化した際のバイト値は同一なのですね。

すると、全ての回答が全文表示されます。
  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.4

だからなんで > というUnicode上の文字集合に復帰させると思います。 こんなことをするの? UTF-8とASCIIに互換性があるというのは「符号化した結果」の話なのに 符号化する前に話を戻すのはナンセンスです。

すると、全ての回答が全文表示されます。
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.3

No1です。 コードポイントを求めた時点ですでにUTF-8では無くなっていますけど。 英字の A を、0x41 というコードで表現すると言う意味でUS-ASCIIもUTF-8も同じです。

1000vicki
質問者

補足

>英字の A を、0x41 というコードで表現すると言う意味でUS-ASCIIもUTF-8も同じです。 あー・・・。 ひょっとしてこう考えるといいのかな? 0x41(何かしらの方法でAという文字をunpackしたあと)というバイト列を 再度なにかしら言語でpackして任意の文字コードの文字集合上のAに復帰させる場合に 0x41はpackしてAという文字に戻すにしてもASCIIコードとしても復帰させれるし、 UTF-8エンコーディングとしても復帰できるといった感じ。 うーん。 あるいはUTF-8のAをunpackしても0x41が返ってくるし US-ASCIIで記述したファイルのAでもunpackすると0x41が返ってくる。 こう捉えたほうがいいのでしょうか?

すると、全ての回答が全文表示されます。
  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.2

> 結局Unicodeコードポイントに直した場合【00】という上位バイトが無駄にくっついてきて【0x0041】となり 上位に00をつけた時点でUTF-8じゃないよね。 あなたはUTF-8じゃないものとASCIIコードを比較して互換性がないと言っているだけ。

1000vicki
質問者

補足

>上位に00をつけた時点でUTF-8じゃないよね。 いえ、ですからUTF-8はUnicodeの文字集合上の符号位置をそれぞれ1byteや2byteあるいは3byteのバイト列に符号化することをいいますよね? この点はお分かりですよね? で2byteや3byteのマルチバイトに符号化されたバイト列は Unicode上の符号位置に復帰させないとどのような文字をいみしているかがわからないわけですよね? そこでRFC等で定義されている計算仕様で例えば【E38182】というバイト列を【3042】 というUnicode上の文字集合に復帰させると思います。 でこれは、1byteで符号化されたバイト列も例外ではないですよね? とするならば、【41】というバイト列もUnicode上の符号位置へ復帰させるために Unicode上の符号位置とバイト数をあわせるために【00】を付ける必要があるのでは? という意味です。

すると、全ての回答が全文表示されます。
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.1

Aを0x0041で表現するのはUTF-16であり、UTF-8ではありませんので、関係ありません。 ユニコードの A (U+0041) を 0x41 として表現するのがUTF-8です。 ユニコードの A (U+0041) は ASCIIの A (0x41) と同じ文字であると定義されていて、UTF-8ではそれが同じコードで表現されているというのが互換性です。 >UTF-8っていうことは最終的にはUnicode上のコードポイントの値・・・つまり0x0041という値に復元?(というのでしょうか)するわけですよね? このあたりが意味不明の文になってしまっています。「最終的」とは? もしかして、画面表示のためにフォントファイルの中からAに相当するフォントデータを探してくるということを言ってますか?それは実装依存でしょうね。

1000vicki
質問者

補足

>ユニコードの A (U+0041) を 0x41 として表現するのがUTF-8です。 Unicodeのコードポイント上にあるU+0041という符号位置をUTF-8の符号化定義に則って Aという文字は符号化されて0x41というバイト値であらわされているわけですよね? 例えば【あ】という文字の場合Unicode上ではU+3042となっているコードポイントを UTF-8の符号化規則にのっとって【e38182】という16進数の3byte値になります。 ただこれは、符号化した結果であって、【e38182】=>【U+3042】ともとのUnicode上のコードポイントU+3042を参照する必要があるとおものですが 【A】という文字も【41】=>【U+0041】の位置に復元する必要があるのでは?と思ったのです。 ただ、 >ユニコードの A (U+0041) は ASCIIの A (0x41) と同じ文字であると定義されていて、 >UTF-8ではそれが同じコードで表現されているというのが互換性です。 とありますが? 例えばUTF-8の UCS-4 範囲 (hex.) UTF-8 8 ビットバイトシーケンス (binary) 0000 0000-0000 007F 0xxxxxxx 0000 0080-0000 07FF 110xxxxx 10xxxxxx 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx 【あ】という日本語はUTF-8という符号化仕様であれば、3行目の 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx が当てはまります。 これを元にUnicode上のU+3042という符号位置を求める計算をするわけですが・・・。 では、【A】の場合は1行目の 0000 0000-0000 007F 0xxxxxxx に当てはまります。 UTF-8による符号化の場合で、かつ1byte以下の数値・・・つまり01111111以下の数値の場合は Unicode上のコードポイントを参照せず、そのままASCIIコードを直接参照するということですか? もっと言えば、 UTF-8による符号化は0~01111111(0xxxxxxx)の範囲はUS-ASCIIの文字集合参照 それ以降(110xxxxx 10xxxxxx ~)はUTF-8の符号化仕様にのっとって符号化する という捉え方でよいのでしょうか?

すると、全ての回答が全文表示されます。