Wie viele Bytes braucht ein Unicode-Zeichen?

Ich bin etwas verwirrt über Kodierungen. Soweit ich weiß, nahmen alte ASCII-Zeichen ein Byte pro Zeichen. Wie viele Bytes benötigt ein Unicode-Zeichen?

Ich nehme an, dass ein Unicode-Zeichen jedes mögliche Zeichen aus jeder Sprache enthalten kann – bin ich richtig? Wie viele Bytes braucht es also pro Zeichen?

Und was bedeuten UTF-7, UTF-6, UTF-16 usw.? Sind sie verschiedene Versionen von Unicode?

Ich habe den Wikipedia-Artikel über Unicode gelesen, aber es ist ziemlich schwierig für mich. Ich freue mich auf eine einfache Antwort.

Solutions Collecting From Web of "Wie viele Bytes braucht ein Unicode-Zeichen?"

Sie werden keine einfache Antwort sehen, weil es keine gibt.

Erstens enthält Unicode nicht “jedes Zeichen aus jeder Sprache”, obwohl es sicher versucht.

Unicode selbst ist ein Mapping, es definiert Codepoints und ein Codepoint ist eine Zahl, die normalerweise mit einem Zeichen verknüpft ist. Ich sage normalerweise, weil es Konzepte gibt, wie Charaktere zu kombinieren. Vielleicht sind Sie mit Akzenten oder Umlauten vertraut. Diese können mit einem anderen Zeichen wie einem a oder einem u , um ein neues logisches Zeichen zu erstellen. Ein Zeichen kann daher aus 1 oder mehreren Codepunkten bestehen.

Um in Computersystemen nützlich zu sein, müssen wir eine Repräsentation für diese Information wählen. Dies sind die verschiedenen Unicode-Kodierungen, wie utf-8, utf-16le, utf-32 usw. Sie unterscheiden sich hauptsächlich durch die Größe ihrer Codeeinheiten. UTF-32 ist die einfachste Kodierung, es hat eine Codeeinheit, die 32 Bit ist, was bedeutet, dass ein individueller Kodepunkt bequem in eine Codeeinheit passt. Die anderen Codierungen haben Situationen, in denen ein Codepunkt mehrere Codeeinheiten benötigt oder dieser bestimmte Codepunkt überhaupt nicht in der Codierung dargestellt werden kann (dies ist beispielsweise bei UCS-2 ein Problem).

Aufgrund der Flexibilität des Kombinierens von Zeichen kann selbst innerhalb einer gegebenen Codierung die Anzahl von Bytes pro Zeichen abhängig von dem Zeichen und der Normalisierungsform variieren. Dies ist ein Protokoll für den Umgang mit Zeichen, die mehr als eine Darstellung haben (Sie können "an 'a' with an accent" sagen, das sind 2 Codepunkte, von denen einer ein kombinierendes Zeichen oder "accented 'a'" ist) ).

Merkwürdigerweise hat niemand darauf hingewiesen, wie berechnet werden soll, wie viele Bytes ein Unicode-Zeichen benötigt. Hier ist die Regel für UTF-8-codierte Strings:

 Binary Hex Comments 0xxxxxxx 0x00..0x7F Only byte of a 1-byte character encoding 10xxxxxx 0x80..0xBF Continuation bytes (1-3 continuation bytes) 110xxxxx 0xC0..0xDF First byte of a 2-byte character encoding 1110xxxx 0xE0..0xEF First byte of a 3-byte character encoding 11110xxx 0xF0..0xF4 First byte of a 4-byte character encoding 

Also die schnelle Antwort ist: es dauert 1 bis 4 Bytes, abhängig von der ersten, die angibt, wie viele Bytes es aufnehmen wird.

Aktualisieren

Wie bereits erwähnt , gilt diese Regel nur für UTF-8

Ich weiß, dass diese Frage alt ist und bereits eine akzeptierte Antwort hat, aber ich möchte ein paar Beispiele anbieten (in der Hoffnung, dass es jemandem nützlich sein wird).

Soweit ich weiß, nahmen alte ASCII-Zeichen ein Byte pro Zeichen.

Recht. Da ASCII eine 7-Bit-Codierung ist, unterstützt es tatsächlich 128 Codes (von denen 95 druckbar sind), so dass es nur ein halbes Byte verwendet (wenn das Sinn macht).

Wie viele Bytes benötigt ein Unicode-Zeichen?

Unicode ordnet nur Zeichen den Codepunkten zu. Es wird nicht definiert, wie sie codiert werden. Eine Textdatei enthält keine Unicode-Zeichen, sondern Bytes / Oktette, die Unicode-Zeichen darstellen können.

Ich nehme an, dass ein Unicode-Zeichen jedes mögliche Zeichen aus jeder Sprache enthalten kann – bin ich richtig?

Nein, aber fast. Also grundsätzlich ja. Aber immer noch nicht.

Wie viele Bytes braucht es also pro Zeichen?

Genau wie deine zweite Frage.

Und was bedeuten UTF-7, UTF-6, UTF-16 usw.? Sind sie eine Art Unicode-Versionen?

Nein, das sind Kodierungen. Sie definieren, wie Bytes / Oktetts Unicode-Zeichen darstellen sollen.

Ein paar Beispiele. Wenn einige davon nicht in Ihrem Browser angezeigt werden können (wahrscheinlich weil die Schriftart diese nicht unterstützt), gehen Sie zu http://codepoints.net/U+1F6AA (ersetzen Sie 1F6AA durch den Codepunkt in 1F6AA ), um ein Bild zu sehen.

    • U + 0061 LATEIN KLEINER BUCHSTABE A: a
      • Nr .: 97
      • UTF-8: 61
      • UTF-16: 00 61
    • U + 00A9 COPYRIGHT ZEICHEN: ©
      • Nr .: 169
      • UTF-8: C2 A9
      • UTF-16: 00 A9
    • U + 00AE REGISTRIERTE ZEICHEN: ®
      • Nº: 174
      • UTF-8: C2 AE
      • UTF-16: 00 AE
    • U + 1337 ÄTHIOPISCHE 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 PRO MILLE ZEICHEN:
      • Nº: 8240
      • UTF-8: E2 80 B0
      • UTF-16: 20 30
    • U + 20AC EURO ZEICHEN:
      • Nº: 8364
      • UTF-8: E2 82 AC
      • UTF-16: 20 AC
    • U + 2122 HANDELSZEICHEN:
      • Nº: 8482
      • UTF-8: E2 84 A2
      • UTF-16: 21 22
    • U + 2603 SCHNEEMANN:
      • Nr .: 9731
      • UTF-8: E2 98 83
      • UTF-16: 26 03
    • U + 260E SCHWARZES TELEFON:
      • Nr .: 9742
      • UTF-8: E2 98 8E
      • UTF-16: 26 0E
    • U + 2614 REGENSCHIRM MIT REGENTROPFEN:
      • Nr .: 9748
      • UTF-8: E2 98 94
      • UTF-16: 26 14
    • U + 263A WEISSES LÄCHELNES GESICHT:
      • Nr .: 9786
      • UTF-8: E2 98 BA
      • UTF-16: 26 3A
    • U + 2691 BLACK FLAG:
      • Nr .: 9873
      • UTF-8: E2 9A 91
      • UTF-16: 26 91
    • U + 269B ATOM-SYMBOL:
      • Nr .: 9883
      • UTF-8: E2 9A 9B
      • UTF-16: 26 9B
    • U + 2708 FLUGZEUG:
      • Nr .: 9992
      • UTF-8: E2 9C 88
      • UTF-16: 27 08
    • U + 271E SCHATTIERTES WEISSES LATEINKREUZ:
      • Nº: 10014
      • UTF-8: E2 9C 9E
      • UTF-16: 27 1E
    • U + 3020 POST MARK FACE:
      • Nr .: 12320
      • UTF-8: E3 80 A0
      • UTF-16: 30 20
    • U + 8089 CJK UNIFIED IDEOGRAPH-8089:
      • Nº: 32905
      • UTF-8: E8 82 89
      • UTF-16: 80 89
    • U + 1F4A9 PFEIL VON POO: 💩
      • Nr .: 128169
      • UTF-8: F0 9F 92 A9
      • UTF-16: D8 3D DC A9
    • U + 1F680 ROCKET: 🚀
      • Nº: 128640
      • UTF-8: F0 9F 9A 80
      • UTF-16: D8 3D DE 80

Okay, ich werde davongetragen …

Lustige Fakten:

  • Wenn Sie nach einem bestimmten Charakter suchen, können Sie ihn auf http://codepoints.net/ kopieren und einfügen.
  • Ich verschwendete viel Zeit auf dieser nutzlosen Liste (aber es ist sortiert!).
  • MySQL hat einen Zeichensatz namens “utf8”, der keine Zeichen länger als 3 Bytes unterstützt. Sie können also keinen Haufen Puh einfügen , das Feld wird still abgeschnitten. Verwenden Sie stattdessen “utf8mb4”.
  • Es gibt eine Schneemann-Testseite (unicodesnowmanforyou.com) .

Einfach ausgedrückt ist Unicode ein Standard, der allen Charakteren der Welt eine Nummer (den sogenannten Codepunkt) zuweist (die noch in Arbeit ist).

Jetzt müssen Sie diese Codepunkte mit Bytes darstellen, das heißt character encoding . UTF-8, UTF-16, UTF-6 sind Möglichkeiten, diese Zeichen darzustellen.

UTF-8 ist Multibyte-Zeichencodierung. Zeichen können 1 bis 6 Bytes haben (einige davon sind möglicherweise gerade nicht erforderlich).

UTF-32 jede Zeichen haben 4 Bytes ein Zeichen.

UTF-16 verwendet 16 Bit für jedes Zeichen und es stellt nur einen Teil der Unicode-Zeichen dar, die als BMP bezeichnet werden (für alle praktischen Zwecke reicht es aus). Java verwendet diese Codierung in seinen Strings.

In Unicode ist die Antwort nicht einfach gegeben. Das Problem, auf das Sie bereits hingewiesen haben, sind die Kodierungen.

Bei einem englischen Satz ohne diakritische Zeichen wäre die Antwort für UTF-8 so viele Bytes wie Zeichen und für UTF-16 wäre es die Anzahl der Zeichen mal zwei.

Die einzige Kodierung, bei der wir (jetzt) ​​die Aussage über die Größe treffen können, ist UTF-32. Da ist es immer 32bit pro Zeichen, obwohl ich mir vorstelle, dass Codepunkte für ein zukünftiges UTF-64 vorbereitet sind 🙂

Was es so schwierig macht, sind mindestens zwei Dinge:

  1. Zusammengesetzte Zeichen, bei denen statt der Zeicheneinheit, die bereits akzentuiert / diakritisch ist (À), ein Benutzer entschieden hat, den Akzent und das Basiszeichen (A) zu kombinieren.
  2. Codepunkte. Codepunkte sind die Methode, mit der die UTF-Codierungen mehr als die Anzahl der Bits codieren können, die ihnen normalerweise ihren Namen geben würde. ZB kennzeichnet UTF-8 bestimmte Bytes, die für sich alleine ungültig sind, aber wenn ihnen ein gültiges Fortsetzungsbyte folgt, wird es möglich sein, ein Zeichen jenseits des 8-Bit-Bereichs von 0..255 zu beschreiben. Siehe die folgenden Beispiele und überlangen Kodierungen im Wikipedia-Artikel zu UTF-8.
    • Das ausgezeichnete Beispiel ist, dass das Zeichen € ( U+20AC entweder als Drei-Byte- Sequenz E2 82 AC oder als Vier-Byte- Sequenz F0 82 82 AC .
    • Beide sind gültig, und dies zeigt, wie kompliziert die Antwort ist, wenn man über “Unicode” spricht und nicht über eine spezifische Kodierung von Unicode, wie UTF-8 oder UTF-16.

In 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 

In UTF-16:

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

In UTF-32:

 4 bytes: 0 - 10FFFF 

10FFFF ist definitionsgemäß der letzte Unicode-Codepunkt, und es ist so definiert, weil es das technische Limit von UTF-16 ist.

Es ist auch der größte Codepunkt, den UTF-8 in 4 Byte codieren kann, aber die Idee hinter der Codierung von UTF-8 funktioniert auch bei Codierungen mit 5 und 6 Byte, um Codepunkte bis 7FFFFFFF abzudecken, d. die Hälfte von dem, was UTF-32 kann.

Es gibt ein großartiges Werkzeug zum Berechnen der Bytes einer beliebigen Zeichenfolge in UTF-8: http://mothereff.in/byte-counter

Update: @mathias hat den Code veröffentlicht: https://github.com/mathiasbynens/mothereff.in/blob/master/byte-counter/eff.js

Nun, ich habe gerade die Wikipedia-Seite darauf gelesen, und im Intro-Teil sah ich, dass “Unicode durch verschiedene Zeichenkodierungen implementiert werden kann. Die gebräuchlichsten Kodierungen sind UTF-8 (das ein Byte für beliebige ASCII-Zeichen verwendet dieselben Code-Werte in UTF-8 und ASCII-Codierung, und bis zu vier Bytes für andere Zeichen), das jetzt veraltete UCS-2 (das für jedes Zeichen zwei Byte verwendet, aber nicht jedes Zeichen im aktuellen Unicode-Standard codieren kann) ”

Wie dieses Zitat zeigt, ist Ihr Problem, dass Sie davon ausgehen, Unicode ist eine einzige Möglichkeit zur Codierung von Zeichen. Es gibt tatsächlich mehrere Formen von Unicode, und wiederum in diesem Zitat hat einer von ihnen sogar 1 Byte pro Zeichen genau wie Sie es gewohnt sind.

Ihre einfache Antwort ist also, dass sie variiert.

Für UTF-16 benötigt das Zeichen vier Bytes (zwei Code-Einheiten), wenn es mit 0xD800 oder größer beginnt; Ein solches Zeichen wird als “Ersatzpaar” bezeichnet. Genauer gesagt, ein Ersatzpaar hat die Form:

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

wobei […] eine Zwei-Byte-Code-Einheit mit dem angegebenen Bereich angibt. Alles < = 0xD7FF ist eine Code-Einheit (zwei Bytes). Alles> = 0xE000 ist ungültig (außer Stücklistenmarkierungen, wohl).

Siehe http://unicodebook.readthedocs.io/unicode_encodings.html , Abschnitt 7.5.

Sehen Sie sich diesen Unicode-Code-Konverter an . 0x2009 Sie beispielsweise 0x2009 , wobei 2009 die Unicode-Nummer für Thin Space ist , im Feld “0x … Notation” ein und klicken Sie auf “Konvertieren”. Die Hexadezimalzahl E2 80 89 (3 Byte) erscheint im Feld “UTF-8 Code Units”.