文字コードUnicodeとUTF-8の違いを理解していない方が結構居るようなので、文字コードの考え方を元に解説してみようと思う。文字コードとは何か?文字コードとは、コンピュータ上で文字を扱うために、文字に対して割り当てられた数値のことであり、文字と数値の対応付けと呼べる。この対応付けの種類は沢山あって、Shift-JISであったり、UTF-8であったりする。以上!と言いたいけど、文字コードはこんなに単純ではない。文字コードを複雑にする要素は沢山あるが、今回の記事ではUnicodeとUTF-8の違いに焦点を絞って解説してみたいと思う。文字コードの世界は以下の2つの要素で構成されている。この違いを意識しておかないと混乱を招くだろう。文字集合を構成する個々の文字の表現方法(数値の振り方)世界中には日本語や英語、ドイツ語、中国語・・・など、大量の文字が存在する。これらの文字から表現したい文字の範囲(集合体)を定義する。これが(1)の文字集合だ。次に(1)の個々の文字をコンピュータ上でどういった数値で表現するかを定義する。この数値の振り方が符号化方式(2)である。コンピュータはこの(2)で割り当てられた数値を用いて文字を表現する。この文字集合と符号化方式を混合している方がよく居るが、この2つの考え方を理解すればUnicodeとUTF-8の違いも分かるだろう。Unicodeは文字集合(1)であり、UTF-8は符号化方式(2)なのだ。同じようにUnicode用の符号化方式としてUTF-16やUTF-32が存在する。これらはUnicode文字集合に対する数値の振り方こそ違うものの、同じ文字集合から作られているから、表現できる文字の種類は同じなのだ。UnicodeとUTF-8を混合してしまうのか?そもそも文字コードに興味の無い人が多くて、UTF-8はUnicodeの一部ような、ぼんやりしたイメージしか持っていない人が多い。言うなら以下の2つだと思う。Unicodeを符号化方式として扱っているソフトウェアの存在よくネタとして挙がるのがWindowsのメモ帳。ファイルを保存する場合、以下の文字コードを選択できる。endian」なるコードも選べてしまう。この表示、文字集合と符号化方式について理解していても混乱してしまう。Unicodeって文字集合だよね??符号化方式ではないのにファイル保存の形式に選べるってどういうこと??実はWindowsのメモ帳でUnicodeを選択した場合の符号化方式は「UTF-16」と決められている。endian」は同じUTF-16だがエンディアンが異なる。エンディアンとはエンディアンとは複数バイトで構成されるデータの並べ方の事で、ビッグエンディアンとリトルエンディアンがある。「0xABCD」という、2バイトのデータがあったとき、これを「ABCD」と並べるか「CDAB」と並べるかが異なる。前者がビッグエンディアン、後者がリトルエンディアンである。人の目から見ると「ABCD」の方が分かりやすいけど、コンピュータ視点で見ると「CDAB」の方が操作しやすい。(計算は下の桁から始めるから、下位バイトが先に読み込めた方がコンピュータ的には都合が良い。人には見にくいけど)試してみた。endian、UTF-8で保存したファイルをそれぞれ用意。ファイル内の文字はすべて同じ。(CRLF)やはり「Unicode.txt」、「UnicodeBigEndian.txt」は両方ともUTF-16みたいだ。下記、エンディアンの判別方法を修正しました。リトルエンディアン・ビッグエンディアンの記載が逆となっておりました。>今回はodコマンドを利用してファイルのバイナリ表現を出力する。x1オプションを付与して実行する。x1を付与しないとリトルエンディアンを意識した出力(前後逆にする)となってしまう。94やはり「Unicode.txt」はリトルエンディアンで、「UnicodeBigEndian」はビッグエンディアンだ。ちなみに、エンディアンはファイルの先頭2バイトで確認できる。この2バイトの事をBOM(ByteOrderMark)といい、エンディアンの判別に利用される。(BOMが付与されていない場合はビッグエンディアンとして扱われる)BOMが「fffe」の場合:リトルエンディアン「feff」の場合:ビッグエンディアンと判別できる。コードポイントが紛らわしい文字集合にはコードポイントという符号化方式とは異なる数値の振り方がある。コードポイントとは?文字集合では、個々の文字に対して、文字集合内での符号位置が決められている。これをコードポイントという。言い方を変えると、「文字集合を構成する文字を並べて、頭から順番に振った数値」のことだ。このコードポイントはあくまで”その文字の文字集合内での位置”であり、符号化方式ではない。「ほげふが」のUnicodeのコードポイントは以下の通りである。U+304CこのU+XXXXはただの符号位置を表す数値なので、この値でデータを保存しても意味が無い。文字を表現したい場合はコードポイントではなく、符号化されたByte列を用いる必要があるのだ。このコードポイント、ぱっと見で符号化方式に見えてしまう。この点を理解していない方は混乱すると思う。コードポイントの利用場面コードポイントは様々な場面で利用されている。Javaのプロパティファイル(.propertiesファイル)に日本語を記述する場合などだ。Javaのプロパティファイルは文字コード「ISO-8859-1」で記述するというルールがある。「ISO-8859-1」はほとんどASCII文字しか扱えなから、表現したい文字のUnicodeコードポイントをプロパティファイルに記述する。「message=こんにちは」といったプロパティを定義する場合、message=\u3053\u3093\u306B\u3061\u306Fと定義する必要がある。\uは後続の文字がコードポイントを表していることを指し、その後ろにコードポイントを記載する。コードポイントの指す文字は「こんにちは」であるが、コードポイント自体は数値とアルファベットでのみ構成されるため、「ISO-8859-1」でも問題無く保存できるという訳だ。この文字からコードポイントへの変換は通常IDEが自動的に実施するが、ファイルの実体はUnicodeコードポイントで表現されている。「native2ascii」を使えばファイル内の「ISO-8859-1」が表現できない文字を手動でUnicodeコードポイントに変換できる。5.0からはxml形式のプロパティファイルを扱えるようになり、これをを利用すれば自由に文字コード指定できるようになった。これ以外にもUnicodeコードポイントを利用する例は多々あるが、コードポイントは符号位置(文字集合内の文字の位置)であって、符号化方式ではない。そのためコードポイントはUnicodeの符号化方式であるUTF-8やUTF-16とは直接は関係しない。簡単だけど、文字集合と符号化文字をまとめてみた。文字コード関連では他にも色々とおもしろいネタがあるので、今後も時間を見て書いていくことにする。ーシステム起動編ー2014年6月10日、とうとうRHEL7が正式リリースを迎えた。前回の記事「Systemd」を理解するーシステム起動編ーでは、Systemdの概念とSystemdに記事を読むLinuxプロセス起動時の環境変数ダンプの取得UnixやLinux上で不具合の調査等々を行う際、特定のプロセス起動時の環境変数を知りたい場合がある記事を読むJava8のインタフェース実装から多重継承とMixinを考える2014年3月18日、ついにJava8が正式にリリースを迎えた。-SIGINTの違いからLinuxプロセスグループを理解するしばらくLinuxネタが続く・・。近いうちに最近出たJava8ネタを書いてみようと思います。今回も前回の記事につづき、Java8による変更点で未だあまり紹介されていないポイントを記事にしようと記事を読むsshd再起動時にssh接続が継続する動作についてLinux/Unixサーバにsshしている際、sshdを再起動したとする。00:25はじめまして、文字化け問題を検索していてたどり着きました。WordPressを使用しており、テーブル作成が簡単に行えるTablePressというプラグインを導入しました。csvファイルを読み込んでテーブルを作ることもできるそうなので、試してみたところ文字化けが起こって困っていました。多くの人はUTF-8(BOM)なしで解決できているそうなのですが、私の場合解決に至らず困っていました。文字化けの仕方がこの記事に書かれている「u」から始まる英数字でした。“テスト”と入力すると”u30c6u30b9u30c8′′となってしまいます。いった場合はまずどこを疑えば良いべきなのでしょうか・・・。教えていただけませんでしょうか。Endianだと思うのですが。これも逆だと思います。02:27>しのぶ様コメントありがとうございます。ご指摘の通りリトルエンディアンとビッグエンディアンの記載が逆となっておりました。記事の内容は修正しております。記事中でファイルのバイナリ表現の取得にodコマンドを利用しておりましたが、odコマンドはエンディアン依存の出力を行うため、筆者のリトルエンディアン環境では、前後逆表記となったバイナリ表現が出力された状態(実際のファイル内容とは異なるバイナリ表現)となっておりました。x1オプションを指定し、1バイト単位でのバイナリ表現を取得することでエンディアンの置き換えが行われないよう記事は修正しております。(併せてエンディアンの判別部分も記載を修正しております)今回はご指摘いただきありがとうございました。>>Unicodeは文字集合(1)であり、UTF-8は符号化方式(2)なのだ。Format-8”の略で文字符号化スキームのうちの1つであると理解していました。よってUnicodeはUCSとUTF-8を両方を含むと...。10:49「コードポイントの利用場面」が間違ってますよ。Javaのプロパティファイル(.propertiesファイル)に日本語を記述する場合などだ。ありますが、実際にはコードポイントを直接利用することなんてまずありません。プロパティファイルに記述する値はコードポイントではなく、UTF-16のコード値です。Javaなんですから。これではあなたが『「UnicodeとUTF-16」もしくは「文字集合と符号化方式」の違いを理解していない人』ということになってしまいますよ。BPMしかなかった頃に限って言えば、コードポイントとUTF-16のコード値は一致しており、正しいと言えましたが、UnicodeがBPM以外にも拡張されたのは2001年です。それ以降は、コードポイントとUTF-16のコード値を区別する必要ができました。23:55わかりやすかったです。ありがとうございます。コメントをキャンセルメールアドレスが公開されることはありません。ーシステム起動編ー2014年6月10日、とうとうRHEL7が正式リリースを迎えた。