• 締切済み

UTF-8とUTF-16およびUTF-32について

Yune-Kichiの回答

回答No.9

# この回答での前提条件:1バイト = 1オクテット = 8ビット > UTF-8なら2byteのときあるいあは3byteの時などありますが、 > 文字によって符号化時の上位・下位の有無が存在し(2byteの時は上位・下位存在するが、 > じゃあ3byteの時の上位・下位はどうやってきめるのか?決めようがないよね?という意?)整合性がないからというような捉え方ですかね? 整合性云々ではなく,そもそも存在しないのです。 まず,エンコーディングは「何ビット単位のデータか」ということが規定されます。 UTF-8であれば8ビット単位ですし,UTF-16であれば16ビット単位です。 UTF-8で3バイトになるというのは,8ビットのデータが3つ並ぶという意味であって,24ビット単位のデータを扱う,ということではありません。 次に,現実的なデータの取り扱い(メモリや通信等)は「1バイト = 8ビット単位」です。 便宜的に,以下ではこれを「データ取扱単位」と呼びます。 エンディアンは「エンコーディングでの単位データの並び方」を規定するのではなく,「現実的なデータの取り扱い上での8ビットを越えるデータの並び方」の規定です。 UTF-8は8ビット単位のデータを取り扱います。エンコーディングのデータサイズとデータの取り扱いサイズに違いがないため,エンディアンは発生しません。 UTF-16は16ビット単位のデータを取り扱います。なので,16ビット/8ビット=2データ取扱単位をどう並べるか,という2種類のエンディアンが発生します。 UTF-32は32ビット単位のデータを取り扱います。なので,32ビット/8ビット=4データ取扱単位をどう並べるか,という4!=24種類のエンディアンが発生します。現実的にはビッグ/リトルの2種類ですが。 CPUのエンディアンの話を書かれている方がいましたが,UTF-16/32と直接関わりません。 LEであるIntelプロセッサ上でUTF-16 BE/UTF-16 LEのどちらのデータも読み書きできます。 ただ,CPUにエンディアンがある原因は同じ理由で,「現実的なデータの取り扱い上での8ビットを越えるデータの並び方」をどう定めるか,という問題が発生するためです。

1000vicki
質問者

補足

>エンディアンは「エンコーディングでの単位データの並び方」を規定するのではなく, >「現実的なデータの取り扱い上での8ビットを越えるデータの並び方」の規定です。 うーんつまり、兎にも角にも,8bit単位で符号化されるUTF-8にはエンディアンが発生しようが ないということなのですね。 wikiからだと >エンディアン (英: endianness) とは、 >多バイトのデータ(即ち基本情報記憶単位を超えるデータ)を >メモリ上に配置する方式の種類のこと。 本回答の前の回答にも >さて,最初に書きましたがエンディアンは「2バイト以上の塊」を取り扱う場合の話です。 とありますね。 で、ひょっとすると今回の質問、エンディアン云々以前の問題かもしれませんが 、なぜマルチバイトのデータだと・・・・うーん伝え方が難しいのですが 【あ】なら  BEの場合 feff3042 となって LEの場合 fffe4230というバイト列になります。 なぜ この 30 と 42 という上位のバイト及び下位バイトとよばれる2つのbyteを 前後入れ替えて表現しようとする仕様ができたのでしょうか? もう当初の質問とはそれてしまいますが・・・・。 もともと気になっていたのはこの部分かもしれません。 確かに UTF-16の2byteの場合において1byteごと前後入れ替えてもUnicode上の符号位置に復号しても前バイト列の先頭にfeffやfffeと負荷させておいてコンピューターが復元時にそれぞれの並び順の仕様にもとづいて矛盾は でてこないのでしょうけれど・・・一つの表現というかそもそもUnicode上の符号位置がビックエンディアンで定義付け しているのだからわざわざリトル・エンディアンなんて仕様つくらなければよかったのにとおもったのですが・・・・ この理由っていったいなんなのでしょうか? 正直wikiにあるメモリ上のアドレス位置がどうのこうのいわれてもC言語の世界になっていてさっぱりわかりません・・・orz。

関連するQ&A

  • UTF-8とUTF-16について質問です。

    まず、【あ】という文字をUTF-16というエンコーディング方式で バイト配列化すると [0] => 66 [1] => 48 というバイト値が帰ってきます。 これはとりあえずC#で処理を行いました。 Encoding encode = Encoding.GetEncoding("UTF-16"); String value = "あ"; Byte [] byteData = encode.GetBytes(value); それでは【あ】という文字の文字集合のコードポイントは右記となります。【0x3042】 これは、出力された 66、48という数値を16進数に変換すると 66=>42 48=>30 となり、リトルエンディアン環境で 0x4230という16進数であらわされるようです。 この点も不思議なのですが今回知りたいのはUTF-16でエンコーディングされた バイト配列はこのように文字集合のコードポイントに復帰?させることができますよね? ではUTF-8でエンコーディングされた【あ】という文字の バイト配列 [0] => 227 [1] => 129 [2] => 130 というバイト配列を上記のような文字集合のコードポイントの値へ復帰させることは できるのでしょうか? それに伴いUTF-8でつかわれる文字集合もUTF-16と同じコードポイントなのでしょうか? 上記 1.UTF-8でエンコーディングされた文字列をバイト配列にした場合 元の文字集合に戻せるのか?戻せるならばその戻し方は? 2.UTF-8がさす文字集合とUTF-16がさす文字集合はおなじものですよね? 上記二点よろしくご教授ください。

  • メモ帳で保存した日本語テキストや日本語XMLをJavaで読込、保存。メモ帳での保存文字コードはなにが推奨されるでしょうか?

     Windows9x系ではないWindowsVistaやXP、NT、2000のメモ帳(Unicodeのbig endianは保存できるがおそらくUnicodeのbig endianでのBOMなし保存不可。UTF-8は保存できるがUTF-8でのBOMなし(UTF-8N)の保存不可。Unicodeのlittle endianは保存できるが仕様なので言うまでもないがUnicodeのlittle endianでのBOMなし保存不可。)で保存した日本語テキストや日本語XMLをJavaで読込、保存。メモ帳での保存文字コードはなにが推奨されるでしょうか? やはりJavaのString型に近いUnicode big endianがよいのでしょうか? それともJava側で自動認識してくれるのでしょうか? XMLの場合は1行目でそのXMLファイルが使用している文字コードが何か宣言しますよね。 でもテキストファイルだと文字コードを宣言する場所がないみたいですし・・・(ここでの文字コードを宣言する場所としてはBOMは例外ですよ 念のため) 補足:メモ帳だとUnicode big endianで保存すると必ずBOMが付くみたいです。 メモ帳はLF改行が使えません。CR+LF改行のみ対応です。

    • ベストアンサー
    • Java
  • UTF-16からUTF-8への変換

    こんにちは。 UTF-16からUFT-8への変換で困っています。 CSVファイルの中にbase64でエンコードされたデータがあり、その中にUTF-16(リトルエンディアン)のデータが埋め込まれています。 base64のデータのデコードは、MIME::Base64のdecode_base64で出来ました。 この中から、文字列を取り出して、uft-8に変換したいのですが、なにかうまい方法はないものでしょうか?

    • ベストアンサー
    • Perl
  • UTF7について

    UTF7についてですがマッピングルールなどについて教えていただけないですか? 試しに「あああ」という文字をフリーのソフトでUTF7に変換したところ 2B 4D 45 49 77 51 6A 42 43 という感じでした。2進数でみてもまったく規則性がわかりません。 UNICODE→UTF8はわかるのですが、UNICODE→UTF7に変換するには どうすればいいのでしょうか?

  • encoding="UTF-16" ってUTF-16で書かれても。

     以前からずっと疑問だったのですが。。。  XML宣言の中に、エンコーディングを記述するところがありますが、その宣言文字列自体をそのエンコーディングで記述するというのはおかしくないでしょうか。  たとえば、UTF-16だったら、 encoding="UTF-16" と書くわけですが、これ自体がUTF-16で書かれているわけですよね? UTF-16で書かれているとわかっていたら宣言する必要はないし、宣言読まないとわからないんだったら、この宣言自体も読めないはずです。  今実際に、UTF-16で書かれていて、エンコーディング宣言もしているXML文書をあるソフトで読もうとしているのですが、1バイト目を読んだところで「Unexpected character. position = 0 」と出力されてエラーになります。  強制的にUTF-16で読ませる昨日もあるので、そうすればエラーは起こりませんが、それじゃエンコーディング宣言の存在自体に意味がないのでは? これは、最初の時点で読めないこと自体がこのソフトの不具合なのでしょうか?  これってどういうことなんでしょう。解決できるんでしょうか。

    • ベストアンサー
    • XML
  • 文字コード結果が違うのはなぜでしょうか?

    文字コード結果が違うのはなぜでしょうか? いつも参考にさせていただいております。ありがとうございます。 VBAにて、文字コード(16進表記)を取得したいのですが、 1.hex(ascw("あ")) 2.Dim ByteData() As Byte  ByteData = "あ" Debug.Print Hex(ByteData(0)) & Hex(ByteData(1)) の2通り行っているのですが、結果が違いました。 1.3042 2.4230 となってしまいます。 UNICODEのリトルエンディアン・ビックエンディアンの違いなのかとも思いましたが、 上記はどちらもVBAで行っているため、式によって扱いが違うとも考えられません。 この違いはなぜなのでしょうか? ご教授よろしくお願いいたします。

  • UTF-8とASCIIコードにおける互換性について

    UTF-8とASCIIはそのASCIIコードの範囲のおいて 互換性を持ちます。(と、書籍や多種な文献にはそういった記述があります) たとえば【A】という文字をUTF-8で符号化した際は【41】(16進数で) さらにASCIIコードでも【41】という値がAという文字に割り当てられています。 確かに、一件互換しているようにみえますが、UTF-8っていうことは最終的には Unicode上のコードポイントの値・・・つまり0x0041という値に復元?(というのでしょうか)するわけですよね? でそのUnicodeの文字集合上から復元したコードポイントに対応する文字を参照しAという文字をみつけてくると・・・。 これって【A】という文字をUTF-8で符号化した歳のバイト列はASCIIと一致しているけれど 結局Unicodeコードポイントに直した場合【00】という上位バイトが無駄にくっついてきて【0x0041】となり 互換性がなくなるのではとおもったのですが・・・。 これはどういう意味の互換性なのでしょうか? 識者の方ご教授ください。 お願い致します。

  • UTF-8にマップできません???

    今、Atomを愛用しております。 チャンと日本語変換できているのに 後半のようなエラーが出るのはなぜでしょうか??? import java.applet.*; // Applet import java.awt.*; // Label, TextField, TextArea, Color, Button import java.awt.event.*; // ActionListener, ActionEvent import java.io.*; // InputStream, BufferedReader, InputStreamReader etc import java.net.*; // URL, Socket, UnknownHostException import java.util.*; // StringTokenizer //public class Chat extends Applet implements Runnable, ActionListener { // Runnable, ActionListenerインターフェース実装 Label TitleLabel; // タイトルラベル TextField InputField; // 入力フィールド Button SendButton; // 送信ボタン Button QuitButton; // 終了ボタン TextArea DisplayArea; // 表示エリア TextArea MemberArea; // メンバーエリア Thread thread; // スレッド Socket socket; // ソケット String Name = null; // 名前 //AudioClip Chime; // チャイム BufferedReader NetInput; // ネットワーク経由入力 PrintStream NetOutput; // ネットワーク経由出力 C:\JAVA>javac Chat.java Chat.java:9: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x93)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x81)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x81)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x8E)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0xC0)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x91)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:9: エラー: この文字(0x95)は、エンコーディングUTF-8にマップできません // Runnable, ActionListener?C???^?[?t?F?[?X???? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x8B)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x89)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^ Chat.java:11: エラー: この文字(0x83)は、エンコーディングUTF-8にマップできません Label TitleLabel; // ?^?C?g?????x?? ^

    • ベストアンサー
    • Java
  • UTF8からUnicode(コードポイント)へ変換

    UTF-8の文字コードをUnicode(コードポイント)へ変換させたいのですが、参考URLの情報のように計算式を知りたいです 。 例えば下の「あ」は、16進では「E38182」、10進では「14909826」ですが、どちらかの値を利用してUnicodeのポイントコード「12354」を計算式を用いて求めたいです。 「あ」 Unicode = 12354 16進 = E38182 10進 = 14909826 参考 http://questionbox.jp.msn.com/qa500194.html

  • 保存形式としてのUnicode、UTF-8

    「Unicode、UTF-8 違い」などでネットを検索すると Unicode・・・文字コード UTF-8・・・符号化方式 とのことで、同次元のものではないとのこと。 しかし、 さくらエディタ、TeraPadなどのテキストエディタの保存形式に Unicode、UTF-8などがあるのですが、この違いは何でしょうか? 前提として、iPhone/iPadにてテキストファイルを扱おうとすると Gmailの添付ファイル、Dropboxなどで文字化けする(デコードできない)ので どちらかの形式に統一しようと思ったのですが、 あとあと困るといやなので、正確に理解したいと思った次第です。 どうぞよろしくお願いします。