1つのUnicode文字は何バイトかかりますか?


239

エンコーディングについて少し混乱しています。私の知る限り、古いASCII文字は1文字あたり1バイトを使用していました。Unicode文字には何バイト必要ですか?

1つのUnicode文字に任意の言語のすべての可能な文字を含めることができると思います-私は正しいですか?それでは、1文字あたり何バイト必要ですか?

そして、UTF-7、UTF-6、UTF-16などはどういう意味ですか?Unicodeの異なるバージョンですか?

Unicodeに関するWikipediaの記事を読みましたが、それは私にとって非常に困難です。簡単な答えを楽しみにしています。



15
申し訳ありませんが、簡単な答えはありません。私はすべてが少し混乱しているのを見つけました。Unicodeは2バイトを使用し、すべての文字を表すことができると請求されましたが、2バイトでは十分ではないことがわかりました。
ジョナサンウッド

12
「簡単な答え」:Unicode文字は1〜4バイトです。Unicodeは多くの言語に対応していますが、すべてに対応しているわけではありません。たとえば、前回見たとき、たとえば、クリンゴンは公式のUnicode文字セットではありませんでした。
Peter

9
クリンゴンは、Unicode標準自体の一部ではありません。代わりに、Uniodeのプライベート使用領域(U + F8D0-U + F8FF)を使用します。
レミールボー

1
救い主の質問-ありがとう。私の状況は、SCORM 1.2に準拠したLMSを介してデータを保存しています... SCORM 1.2の標準 'cmi.suspend_data'は、以前の開発者が4096文字を保存できると想定していた4096バイトのデータです。おお、彼は間違っていた-私はブックマークが長いコースで失敗する理由を発見した。つまり、UTF-8を使用しているので、1文字あたり4バイトが必要で、1024文字が得られることがわかりました。
ダンジャ

回答:


147

簡単な答えはないため、表示されません。

まず、Unicodeには「すべての言語のすべての文字」が含まれているわけではありません。

Unicode自体はマッピングであり、コードポイントを定義し、コードポイントは数値であり、通常は文字に関連付けられています。通常、キャラクターを組み合わせるようなコンセプトがあるからです。アクセントやウムラウトなどに慣れているかもしれません。これらは、aまたはなどの別の文字とともに使用しuて、新しい論理文字を作成できます。したがって、文字は1つ以上のコードポイントで構成できます。

コンピューティングシステムで役立つためには、この情報の表現を選択する必要があります。これらは、utf-8、utf-16le、utf-32などのさまざまなUnicodeエンコーディングです。これらは、コードユニットのサイズによって大きく区別されます。UTF-32は最も単純なエンコーディングで、32ビットのコードユニットを持っています。これは、個々のコードポイントがコードユニットに快適に収まることを意味します。他のエンコーディングは、コードポイントが複数のコードユニットを必要とする、またはその特定のコードポイントがエンコーディングでまったく表現できない状況になります(これは、たとえばUCS-2の問題です)。

文字を組み合わせる柔軟性のため、特定のエンコーディング内でも、文字ごとのバイト数は、文字と正規化形式によって異なる場合があります。これは、複数の表現を持つ文字を処理するためのプロトコルです("an 'a' with an accent"どちらが2つのコードポイントであり、そのうちの1つが結合文字または1つのコードポイントであると言うことができます"accented 'a'")。


1
OK。それでは、特定の1つのコードポイントで表される1つの特定の文字に必要なバイト数は?たとえば、改行しないスペース。
Nicolas Barbulesco、2015年

文字を組み合わせると、UTF8配列でstrlen()、substr()、およびその他の文字列操作関数を作成するときに、プログラマーの生活は地獄になります。この種の作業は決して完了せず、常にバギーです。
Nulik 2016

Windows-1252、UTF8、およびUTF8-BOMでエンコードされたファイルが各エンコードで解釈されることを示し、結果間の同等性を比較するデモを書きました:github.com/vladyrn/encodings_demo
Vlad

195

不思議なことに、1バイトのUnicode charを取得するバイト数を計算する方法は誰も指摘していません。UTF-8でエンコードされた文字列のルールは次のとおりです。

Binary    Hex          Comments
0xxxxxxx  0x00..0x7F   Only byte of a 1-byte character encoding
10xxxxxx  0x80..0xBF   Continuation byte: one of 1-3 bytes following the first
110xxxxx  0xC0..0xDF   First byte of a 2-byte character encoding
1110xxxx  0xE0..0xEF   First byte of a 3-byte character encoding
11110xxx  0xF0..0xF7   First byte of a 4-byte character encoding

したがって、簡単な答えは次のとおりです。最初のバイトに応じて、1バイトから4バイトかかります。


8
4バイト文字の最大16進数値は0xF7(0xF4ではない)だと思います。
DJPJ 2016

どうもありがとうございます!私はIETF標準を制御していただけで、エンコーディングについて何も見つかりませんでした。また、読んでいた記事では、末尾のコードの数を表すために使用されるビット数を詳しく説明するのに十分な詳細がありませんでした。 「キャラクター」あたりのポイント。
MarcusJ 2016

1
これは現在、「新しいチームメンバーの紹介」チートシートの2ページ目にあり、陽気な最初の2つのコメント
Cee McSharpface

1
0xF4は間違いではなく、明確化です。Unicodeコードポイントは0-0x10ffffの範囲にあるため、最後のコードポイントはF4 8F BF BFとしてコード化されます。
Frediano Ziglio

38

私はこの質問が古く、すでに受け入れられた回答があることを知っていますが、いくつかの例を提供したいと思います(誰かに役立つことを願っています)。

私の知る限り、古いASCII文字は1文字あたり1バイトを使用していました。

正しい。実際、ASCIIは7ビットエンコーディングであるため、128個のコード(そのうち95個は印刷可能)をサポートしているため、(意味がある場合)半バイトしか使用しません。

Unicode文字には何バイト必要ですか?

Unicodeは文字をコードポイントにマッピングするだけです。それらをエンコードする方法は定義されていません。テキストファイルにはUnicode文字は含まれていませんが、Unicode文字を表すバイト/オクテットは含まれています。

1つのUnicode文字に任意の言語のすべての可能な文字を含めることができると思います-私は正しいですか?

いいえ。しかし、ほとんど。だから基本的にはい。しかし、まだ違います。

それでは、1文字あたり何バイト必要ですか?

2番目の質問と同じです。

そして、UTF-7、UTF-6、UTF-16などはどういう意味ですか?それらはある種のUnicodeバージョンですか?

いいえ、それらはエンコーディングです。それらは、バイト/オクテットがUnicode文字をどのように表すかを定義します。

いくつかの例。それらの一部がブラウザーで表示できない場合(おそらくフォントがそれらをサポートしていないため)、に移動してhttp://codepoints.net/U+1F6AA1F6AA16進数のコードポイントに置き換えます)、画像を表示します。

    • U + 0061ローマ字小文字A: a
      • Nº:97
      • UTF-8:61
      • UTF-16:00 61
    • U + 00A9著作権記号: ©
      • Nº:169
      • UTF-8:C2 A9
      • UTF-16:00 A9
    • U + 00AE登録記号: ®
      • Nº:174
      • UTF-8:C2 AE
      • UTF-16:00 AE
    • U + 1337 ETHIOPIC SYLLABLE PHWA:
      • Nº:4919
      • UTF-8:E1 8C B7
      • UTF-16:13 37
    • U + 2014 EM DASH:
      • Nº:8212
      • UTF-8:E2 80 94
      • UTF-16:20 14
    • U + 2030 PER MILLE SIGN:
      • Nº:8240
      • UTF-8:E2 80 B0
      • UTF-16:20 30
    • U + 20ACユーロ記号:
      • Nº:8364
      • UTF-8:E2 82 AC
      • UTF-16:20 AC
    • U + 2122商標記号:
      • Nº:8482
      • UTF-8:E2 84 A2
      • UTF-16:21 22
    • U + 2603スノーマン:
      • Nº:9731
      • UTF-8:E2 98 83
      • UTF-16:26 03
    • U + 260E黒電話:
      • Nº:9742
      • UTF-8:E2 98 8E
      • UTF-16:26 0E
    • U + 2614雨滴付き傘:
      • Nº:9748
      • UTF-8:E2 98 94
      • UTF-16:26 14
    • U + 263Aホワイトスマイルフェイス:
      • Nº:9786
      • UTF-8:E2 98 BA
      • UTF-16:26 3A
    • U + 2691ブラックフラグ:
      • Nº:9873
      • UTF-8:E2 9A 91
      • UTF-16:26 91
    • U + 269B ATOM記号:
      • Nº:9883
      • UTF-8:E2 9A 9B
      • UTF-16:26 9B
    • U + 2708飛行機:
      • Nº:9992
      • UTF-8:E2 9C 88
      • UTF-16:27 08
    • U + 271Eシャドウホワイトラテンクロス:
      • Nº:10014
      • UTF-8:E2 9C 9E
      • UTF-16:27 1E
    • U + 3020 POSTAL MARK FACE:
      • Nº:12320
      • UTF-8:E3 80 A0
      • UTF-16:30 20
    • U + 8089 CJK統合IDEOGRAPH-8089:
      • Nº:32905
      • UTF-8:E8 82 89
      • UTF-16:80 89
    • U + 1F4A9 POO OF POO: 💩
      • Nº:128169
      • UTF-8:F0 9F 92 A9
      • UTF-16:D8 3D DC A9
    • U + 1F680ロケット: 🚀
      • Nº:128640
      • UTF-8:F0 9F 9A 80
      • UTF-16:D8 3D DE 80

よし私は夢中になっています...

おもしろ情報:


UTF-16 のコード単位は16ビット幅です。あなたはそれらを真ん中にスペースで示しました、それは誤解を招きやすいです。©のUTF-16表現00A900 A9(UTF-16BEの代わりに)の代わりにすべきです。
Roland Illig 2016年

違いは何ですか?BEはビッグエンディアンを表していないのですか?彼はビッグエンディアンでそれを書いたので、ビッグエンディアンUTF-16で書かれたファイルはUTF-16BEと同じでしょう?
HappyPandaFace 2017年

6
修正:1)ASCIIは7ビット、1バイトは8ビットであるため、半分をはるかに超えています。2)Unicodeはコードポイントのエンコード方法を定義します。UTF-8、UTF-16、UTF-32はUnicode標準で定義されています。
Jonathan Rosenne 2017

3
@JonathanRosenne私は、8ビットで表現できる可能な値の半分だけを使用することを意味していたと思います。ビットの半分を使用するわけではありません。
アリッツロペス

2
私は例が本当に好きです。たとえば、UTF-8よりもUTF-16を好む理由を強調しています。異なるソフトウェアの開発者は、どのUnicode文字が使用される可能性が高いかに基づいて、異なるエンコーディングを選択できます。例えば中国/日本では、UTF-16(2バイト)は、同じ文字は、多くの場合、UTF-8でエンコードするバイト数の倍必要になるので、それらのためのUTF-8よりも理にかなっている
マイク

29

単純に言えばUnicode、世界のすべてのキャラクターに1つの番号(コードポイントと呼ばれる)を割り当てた標準です(現在も機能しています)。

次に、このコードポイントをバイトを使用して表す必要がありますcharacter encodingUTF-8, UTF-16, UTF-6これらの文字を表す方法です。

UTF-8マルチバイト文字エンコーディングです。文字には1〜6バイトを含めることができます(現在、一部の文字は不要な場合があります)。

UTF-32 各文字は4バイトの文字を持っています。

UTF-16各文字に16ビットを使用し、BMPと呼ばれるUnicode文字の一部のみを表します(すべての実用的な目的のために十分です)。Javaは文字列でこのエンコーディングを使用します。


10
Unicodeは21ビットのコードセットであり、UTF-8でUnicode文字を表すには4バイトで十分です。UTF-16はサロゲートを使用してBMP(基本的な多言語プレーン)の外の文字を表します。有効なUnicode文字を表すには、2または4バイトが必要です。UCS-2は、サロゲートまたはBMP外の文字をサポートしないUTF-16の16ビットのみのバリアントでした。
ジョナサンレフラー、2011年

1
あなたは正しいです。UTF-8オリジナルは、32ビットに対応するために6バイトでした。彼はすでにウィキドキュメントと混同されていたので、私は実際にはそれほど複雑にしたくありませんでした:)
ジンババオ

3
この回答は、UTF-16がBMPコードポイントをエンコードできないことを示しています。これらはサロゲートペアを使用してUTF-8と同じようにエンコードできるため、これは正しくありません。(16ビットのコードポイントのみをエンコードしたUnicode 2.0が登場する前に、古いUCS-2を考えている必要があります。)また、JavaはUTF-16をまったく使用せず、コードポイントが変更された形式を使用します。 0は異なる方法でエンコードされます。
rdb 2014

@rdb-それは逆です。その答えは、UTF-16がBMPを表すと述べています。
Nicolas Barbulesco、2015年

3
私はタイプミスしました。私は「非BMP」と言うつもりでした。答えの誤りは、UTF-16がBMP文字を表すと言っていることであり、これは不正確です。UTF-16はすべてのUnicode文字をエンコードできます。非BMP文字はサロゲートペアを介してエンコードされます。おそらく、回答者はUCS-2と混同されていました。
rdb

17

UTF-8の場合:

1 byte:       0 -     7F     (ASCII)
2 bytes:     80 -    7FF     (all European plus some Middle Eastern)
3 bytes:    800 -   FFFF     (multilingual plane incl. the top 1792 and private-use)
4 bytes:  10000 - 10FFFF

UTF-16の場合:

2 bytes:      0 -   D7FF     (multilingual plane except the top 1792 and private-use )
4 bytes:   D800 - 10FFFF

UTF-32の場合:

4 bytes:      0 - 10FFFF

10FFFFは定義により最後のUnicodeコードポイントであり、UTF-16の技術的な制限のため、そのように定義されています。

UTF-8は4バイトでエンコードできる最大のコードポイントでもありますが、UTF-8のエンコードの背後にある考え方は、5および6バイトのエンコードでも機能し、7FFFFFFFまでコードポイントをカバーします。UTF-32ができることの半分。


8

Unicodeでは、答えは簡単には与えられません。すでに指摘したように、問題はエンコーディングです。

分音文字のない英語の文を考えると、UTF-8の答えは文字と同じバイト数であり、UTF-16の答えは文字数の2倍です。

(現時点で)サイズに関するステートメントを作成できる唯一のエンコーディングはUTF-32です。コードポイントは将来のUTF-64に備えて用意されていると思いますが、ここでは常に1文字あたり32ビットです。

それほど難しいのは、少なくとも2つのことです。

  1. 構成された文字。ここで、すでにアクセント/発音区別符号(À)の文字エンティティを使用する代わりに、ユーザーはアクセントとベース文字( `A)を組み合わせることにしました。
  2. コードポイント。コードポイントは、UTFエンコーディングで、通常それらの名前に許可されるビット数よりも多くのビット数をエンコードできる方法です。たとえば、UTF-8は、それ自体が無効である特定のバイトを指定しますが、有効な継続バイトが続く場合、8ビットの範囲0..255を超える文字を記述できます。下記のUTF-8に関するWikipediaの記事のと長すぎるエンコーディングを参照してください。
    • 優れた例として、€文字(コードポイントU+20AC3バイトシーケンスE2 82 ACまたは4 バイトシーケンスのいずれかで表すことができます)がありますF0 82 82 AC
    • どちらも有効であり、これは、UTF-8やUTF-16などのUnicodeの特定のエンコーディングではなく、「Unicode」について話すときの答えがいかに複雑かを示しています。


4

さて、私もWikipediaページをプルアップしました。イントロ部分で、「Unicodeはさまざまな文字エンコーディングで実装できます。最も一般的に使用されるエンコーディングはUTF-8です(これはASCII文字に1バイトを使用します。 UTF-8とASCIIの両方のエンコードで同じコード値、および他の文字は最大4バイト)、現在は廃止されたU​​CS-2(各文字に2バイトを使用しますが、現在のUnicode標準のすべての文字をエンコードすることはできません) "

この引用が示すように、問題は、Unicodeが文字をエンコードする単一の方法であると想定していることです。Unicodeには実際には複数の形式があり、その引用でも、1つは、以前と同じように1文字あたり1バイトです。

だからあなたが望むあなたの簡単な答えはそれが変わるということです。


3

UTF-16の場合、0xD800以上で始まる文字には4バイト(2コード単位)が必要です。このような文字は「サロゲートペア」と呼ばれます。より具体的には、サロゲートペアの形式は次のとおりです。

[0xD800 - 0xDBFF]  [0xDC00 - 0xDFF]

ここで、[...]は、指定された範囲の2バイトのコード単位を示します。0xD7FF未満のものは、1つのコード単位(2バイト)です。0xE000を超えるものはすべて無効です(BOMマーカーを除きます)。

http://unicodebook.readthedocs.io/unicode_encodings.html、セクション7.5を参照してください。



1

Wikiから:

ASCIIとの互換性を最大化する8ビットの可変幅エンコーディングであるUTF-8。

UTF-16、16ビットの可変幅エンコーディング。

UTF-32、32ビット、固定幅エンコーディング。

これらは、最も人気のある3つの異なるエンコーディングです。

  • UTF-8では、各文字は1から4バイトにエンコードされます(主要なエンコード)
  • UTF16では、各文字が1〜2つの16ビットワードにエンコードされ、
  • UTF-32では、すべての文字が単一の32ビットワードとしてエンコードされます。

1

Unicodeすべての文字に一意の番号を提供する標準です。これらの一意の番号はcode point、世界に存在するすべての文字に対してs(単なる一意のコード)と呼ばれます(一部の文字はまだ追加されていません)。

さまざまな目的で、これcode pointsをバイト単位で表す必要がある場合があり(ほとんどのプログラミング言語ではこれを行います)、ここからCharacter Encoding始めます。

UTF-8UTF-16などUTF-32はすべてCharacter Encodingsであり、Unicodeのコードポイントはこれらのエンコーディングでさまざまな方法で表されます。


UTF-8 エンコードは可変幅の長さであり、エンコードされた文字は1バイトから4バイトまでを占めることができます。

UTF-16可変長であり、文字がエンコードされており、1バイトまたは2バイト(8ビットまたは16ビット)を取ることができます。これは、BMP(Basic Multilingual Plane)と呼ばれるすべてのUnicode文字の一部のみを表しており、ほとんどすべての場合に十分です。JavaはUTF-16文字列と文字にエンコーディングを使用します。

UTF-32 固定長であり、各文字は正確に4バイト(32ビット)です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.