41

文字エンコーディングの概念についてかなり混乱しています。

Unicode、GBK などとは何ですか? プログラミング言語はそれらをどのように使用しますか?

それらについて知る必要がありますか?それらに悩まされることなく、より簡単で高速なプログラミング方法はありますか?

4

4 に答える 4

42

(私はこれらの用語のいくつかを大まかに/口語的に使用していることに注意してください.

1 バイトは 256 個の異なる値 (8 ビット) しか持つことができません。

文字セットには 256 文字を超える文字セットがあるため、一般に、各文字がバイトであると単純に言うことはできません。

したがって、文字セット内の各文字を一連のバイトに変換する方法を記述するマッピングが必要です。一部の文字は 1 バイトにマップされる場合がありますが、他の文字は複数のバイトにマップする必要があります。

これらのマッピングは、文字を一連のバイトにエンコードする方法を示しているため、エンコーディングです。

Unicode に関しては、非常に高いレベルで、Unicode はすべての文字に単一の一意の番号を割り当てようとする試みです。256 文字を超えるため、明らかにその数値は 1 バイトよりも広い必要があります :) Java は、すべての文字に 16 ビット値が割り当てられるバージョンの Unicode を使用します (これが、Java 文字が 16 ビット幅で整数を持つ理由です)。 0 から 65535 までの値)。Java 文字のバイト表現を取得するときは、使用するエンコーディングを JVM に伝える必要があります。これにより、JVM は文字のバイト シーケンスを選択する方法を知ることができます。

于 2012-05-16T03:21:13.267 に答える
42

基本はアスキー

元々、1 文字は常に 1 バイトとして格納されていました。1 バイト (8 ビット) には、256 の可能な値を区別する可能性があります。しかし、実際には最初の 7 ビットだけが使用されました。そのため、128 文字のみが定義されました。このセットはASCII 文字セットと呼ばれます。

  • 0x00-0x1Fステアリング コード (CR、LF、STX、ETX、EOT、BEL など) を含む
  • 0x20-0x40数字と句読点を含む
  • 0x41-0x7F主にアルファベット文字を含む
  • 0x80- 0xFF8 番目のビット = 未定義。

フランス語、ドイツ語、およびその他の多くの言語では、追加の文字が必要でした。(例à, é, ç, ô, ...) ASCII 文字セットでは利用できませんでした。そのため、8 番目のビットを使用して文字を定義しました。これは「拡張 ASCII」として知られているものです。

問題は、追加の 1 ビットでは、世界中のすべての言語をカバーするには十分な容量がないことです。したがって、各地域には独自の ASCII バリアントがあります。多くの拡張 ASCII エンコーディングがあります (latin-1非常に一般的なエンコーディングです)。

よくある質問: 「ASCII は文字セットですか、それともエンコーディングですか」 ? ASCII文字セットです。ただし、プログラミングcharsetencodingは、同義語として広く使用されています。ASCII 文字のみを含み、それ以上は何も含まないエンコーディングを参照したい場合 (8 番目のビットは常に 0): それはUS-ASCII.

Unicode はさらに一歩進んでいます

Unicodeは、エンコーディングではなく、文字セットの優れた例です。ASCII 標準と同じ文字を使用しますが、文字を追加してリストを拡張し、各文字に format のコードポイントを与えますu+xxxx。全世界で使用されているすべての文字 (および人気のあるアイコン) を含めるという野心があります。

UTF-8、UTF-16、および UTF-32 は、Unicode 文字テーブルを適用するエンコーディングです。しかし、それらはそれぞれ、それらをエンコードする方法がわずかに異なります。UTF-8 は、ASCII 文字をエンコードするときに 1 バイトのみを使用し、他の ASCII エンコードと同じ出力を提供します。ただし、他の文字の場合、最初のビットを使用して、2 番目のバイトが続くことを示します。

GBKは、UTF-8 と同様に複数のバイトを使用するエンコーディングです。原理はほとんど同じです。最初のバイトは ASCII 規格に従うため、7 ビットのみが使用されます。ただし、UTF-8 と同様に、8 番目のビットを使用して 2 番目のバイトの存在を示すことができ、2 番目のバイトを使用して 22,000 の中国語文字の 1 つをエンコードします。主な違いは、これが Unicode 文字セットに従わないことです。対照的に、一部の中国語文字セットを使用します。

データのデコード

データをエンコードするときはエンコードを使用しますが、データをデコードするときは、どのエンコードが使用されたかを知り、同じエンコードを使用してデコードする必要があります。

残念ながら、エンコーディングは常に宣言または指定されているわけではありません。すべてのファイルに、データが保存されているエンコーディングを示すプレフィックスが含まれていれば理想的でした。しかし、多くの場合、アプリケーションは、使用するエンコーディングを想定または推測する必要があります。(たとえば、オペレーティング システムの標準エンコーディングを使用します)。

多くの開発者はエンコーディングが何であるかさえ知らないため、これについてはまだ認識が不足しています。

MIME タイプ

MIME タイプは、エンコーディングと混同されることがあります。これらは、受信者がどのような種類のデータが到着しているかを識別するのに便利な方法です。これは、HTTP プロトコルが MIME タイプ宣言を使用してそのコンテンツ タイプを定義する方法の例です。

Content-Type: text/html; charset=utf-8

そして、これはもう 1 つの大きな混乱の原因です。MIME タイプは、メッセージに含まれるデータの種類をtext/xml表します (例: 、image/png...)。また、場合によっては、データがどのようにエンコードされるか (つまりcharset=utf-8) も追加で説明します。混乱の2つのポイント:

  1. すべての MIME タイプがエンコーディングを宣言するわけではありません。場合によっては、オプションでしかない場合もあれば、まったく無意味な場合もあります。
  2. 前に説明したように、UTF-8 はエンコーディングであり、文字セットではないため、この構文charset=utf-8はセマンティックの混乱を招きます。しかし、前に説明したように、2 つの単語を同じ意味で使用する人もいます。

たとえばtext/xml、エンコーディングを宣言するのは無意味です (そして、charsetパラメーターは単に無視されます)。代わりに、 XML パーサーは通常、ファイルの最初の行を読み取り、タグを探します。<?xml encoding=...そこにある場合は、そのエンコーディングを使用してファイルを再度開きます。

電子メールの送信時にも同じ問題が存在します。電子メールには、HTML メッセージまたはプレーン テキストのみを含めることができます。その場合も、コンテンツのタイプを定義するために MIME タイプが使用されます。

しかし、要約すると、MIME タイプだけで問題を解決できるとは限りません。

プログラミング言語のデータ型

Java (および他の多くのプログラミング言語) の場合、エンコーディングの危険性に加えて、バイトと整数を文字にキャストする複雑さもあります。これは、コンテンツが異なる範囲に格納されるためです。

  • バイトは符号付きバイト (範囲: -128127) として格納されます。
  • charJavaの型は 2 符号なしバイトに格納されます (範囲: 0- 65535)
  • -1ストリームは~の範囲の整数を返します255

データに ASCII 値のみが含まれていることがわかっている場合。次に、適切なスキルがあれば、データをバイトから文字に解析したり、すぐに文字列にラップしたりできます。

// the -1 indicates that there is no data
int input = stream.read();
if (input == -1) throw new EOFException();

// bytes must be made positive first.
byte myByte = (byte) input;
int unsignedInteger = myByte & 0xFF;
char ascii = (char)(unsignedInteger);

ショートカット

Java でのショートカットは、リーダーとライターを使用し、それらをインスタンス化するときにエンコーディングを指定することです。

// wrap your stream in a reader. 
// specify the encoding
// The reader will decode the data for you
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);

先に XML ファイルについて説明したように、適切な DOM または JAXB マーシャラーはエンコーディング属性をチェックするため、それほど重要ではありません。

于 2015-08-01T10:47:43.910 に答える
4

文字エンコーディングは、自分とは異なる言語を使用する人のためにソフトウェアを作成する際の問題を解決するために使用するものです。

文字が何であるか、どのように並べられているかわかりません。したがって、この新しい言語の文字列がバイナリでどのように表示されるかはわかりませんが、率直に言って、気にする必要はありません。

あなたが持っているのは、あなたが話す言語から文字列が話す言語に文字列を翻訳する方法です (翻訳者と言ってください)。競合することなく両方の言語をバイナリで表現できるシステムが必要です。エンコーディングはそのシステムです。

これにより、言語がバイナリで表現される方法に関係なく機能するソフトウェアを作成できます。

于 2012-05-16T03:31:12.103 に答える