298 Stimmen

Wie viele Bytes umfasst ein Unicode-Zeichen?

Ich bin ein wenig verwirrt über die Kodierungen. Soweit ich weiß, benötigten die alten ASCII-Zeichen ein Byte pro Zeichen. Wie viele Bytes benötigt ein Unicode-Zeichen?

Ich gehe davon aus, dass ein Unicode-Zeichen alle möglichen Zeichen einer beliebigen Sprache enthalten kann - liege ich da richtig? Wie viele Bytes braucht es also pro Zeichen?

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

Ich habe die Wikipedia-Artikel über Unicode aber es ist ziemlich schwierig für mich. Ich bin gespannt auf eine einfache Antwort.

1 Stimmen

18 Stimmen

Tut mir leid, es gibt keine einfache Antwort. Ich finde die ganze Sache ein bisschen verwirrend. Es wurde behauptet, dass Unicode zwei Bytes benötigt und alle Zeichen darstellen kann, aber es hat sich herausgestellt, dass zwei Bytes nicht ganz ausreichend sind.

14 Stimmen

"Einfache Antwort": Ein Unicode-Zeichen benötigt 1-4 Bytes. Unicode deckt viele Sprachen ab, aber nicht alle. Als ich das letzte Mal nachgesehen habe, war Klingonisch zum Beispiel kein offizieller Unicode-Zeichensatz.

262voto

paul.ago Punkte 3634

Seltsamerweise hat niemand darauf hingewiesen, wie man berechnet, wie viele Bytes ein Unicode-Zeichen braucht. Hier ist die Regel für UTF-8 kodierte Zeichenketten:

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

Die schnelle Antwort lautet also: Es braucht 1 bis 4 Bytes, je nach dem ersten, das angibt, wie viele Bytes es braucht.

11 Stimmen

Ich glaube, der maximale Hex-Wert für ein 4-Byte-Zeichen ist 0xF7 (nicht 0xF4).

1 Stimmen

Ich danke Ihnen vielmals! Ich habe den IETF-Standard gerade mit control+f'ing durchforstet und nichts über die Kodierung gefunden, und der Artikel, den ich gelesen habe, ging nicht detailliert genug darauf ein, wie viele Bits verwendet werden, um die Anzahl der hinteren Codepunkte pro "Zeichen" darzustellen.

1 Stimmen

Dies steht jetzt auf der zweiten Seite meines Spickzettels "Einführung für neue Teammitglieder", zusammen mit den beiden lustigen ersten Kommentaren

181voto

Logan Capaldo Punkte 38523

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

Erstens enthält der Unicode nicht "jedes Zeichen aus jeder Sprache", auch wenn er es natürlich versucht.

Unicode selbst ist ein Mapping, es definiert Codepoints und ein Codepoint ist eine Nummer, die mit in der Regel einen Charakter. Ich sage "normalerweise", weil es Konzepte wie die Kombination von Zeichen gibt. Sie sind vielleicht mit Dingen wie Akzenten oder Umlauten vertraut. Diese können zusammen mit einem anderen Zeichen verwendet werden, z. B. mit einem a oder eine u um ein neues logisches Zeichen zu erzeugen. Ein Zeichen kann also aus 1 oder mehreren Codepoints bestehen.

Um in Rechensystemen nützlich zu sein, müssen wir eine Darstellung für diese Informationen wählen. Das 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, sie hat eine Codeeinheit von 32 Bit, was bedeutet, dass ein einzelner Codepunkt bequem in eine Codeeinheit passt. Bei den anderen Kodierungen gibt es Situationen, in denen ein Codepunkt mehrere Codeeinheiten benötigt, oder dieser bestimmte Codepunkt kann in der Kodierung überhaupt nicht dargestellt werden (dies ist zum Beispiel ein Problem bei UCS-2).

Aufgrund der Flexibilität bei der Kombination von Zeichen kann selbst innerhalb einer bestimmten Kodierung die Anzahl der Bytes pro Zeichen je nach Zeichen und Normalisierungsform variieren. Dies ist ein Protokoll für den Umgang mit Zeichen, die mehr als eine Darstellung haben (man kann sagen "an 'a' with an accent" das sind 2 Codepunkte, von denen einer ein kombinierendes Zeichen ist oder "accented 'a'" was einem Codepunkt entspricht).

1 Stimmen

OK. Wie viele Bytes braucht dann ein bestimmtes Zeichen für einen bestimmten Codepunkt? Zum Beispiel, das nicht-umbrechende Leerzeichen.

1 Stimmen

Die kombinierten Zeichen machen einem Programmierer das Leben zur Hölle, wenn es darum geht, strlen(), substr() und andere Funktionen zur Zeichenkettenmanipulation auf UTF8-Arrays zu schreiben. Diese Art von Arbeit wird nie vollständig und immer fehlerhaft sein.

0 Stimmen

Ich habe eine Demo geschrieben, die Windows-1252, UTF8 und UTF8-BOM kodierte Dateien zeigt, die mit jeder Kodierung interpretiert werden, und die Gleichheit der Ergebnisse vergleicht: github.com/vladyrn/encodings_demo

56voto

basic6 Punkte 3313

Ich weiß, diese Frage ist alt und hat bereits eine akzeptierte Antwort, aber ich möchte ein paar Beispiele anführen (in der Hoffnung, dass sie für jemanden nützlich sind).

Soweit ich weiß, benötigten alte ASCII-Zeichen ein Byte pro Zeichen.

Richtig. Da es sich bei ASCII um eine 7-Bit-Kodierung handelt, werden 128 Codes unterstützt (von denen 95 druckbar sind), so dass nur ein halbes Byte verwendet wird (wenn das überhaupt Sinn macht).

Wie viele Bytes benötigt ein Unicode-Zeichen?

Unicode ordnet die Zeichen lediglich den Codepunkten zu. Er definiert nicht, wie sie zu kodieren sind. Eine Textdatei enthält keine Unicode-Zeichen, sondern Bytes/Octets, die Unicode-Zeichen darstellen können.

Ich gehe davon aus, dass ein Unicode-Zeichen alle möglichen Zeichen enthalten kann. Zeichen einer beliebigen Sprache enthalten kann - liege ich da richtig?

Nein. Aber fast. Also im Grunde ja. Aber immer noch nein.

Wie viele Bytes werden also pro Zeichen benötigt?

Dasselbe wie bei Ihrer 2. 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/Octets Unicode-Zeichen darstellen sollen.

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

    • U+0061 LATEINISCHER KLEINBUCHSTABE A: a
      • NR.: 97
      • UTF-8: 61
      • UTF-16: 00 61
    • U+00A9 COPYRIGHT-ZEICHEN: ©
      • Nº: 169
      • UTF-8: C2 A9
      • UTF-16: 00 A9
    • U+00AE EINGETRAGENES ZEICHEN: ®
      • Nº: 174
      • UTF-8: C2 AE
      • UTF-16: 00 AE
    • U+1337 ÄTHIOPISCHE SILBE PHWA:
      • Nº: 4919
      • UTF-8: E1 8C B7
      • UTF-16: 13 37
    • U+2014 EM-BINDESTRICH:
      • NR.: 8212
      • UTF-8: E2 80 94
      • UTF-16: 20 14
    • U+2030 PROMILLEZEICHEN:
      • NR.: 8240
      • UTF-8: E2 80 B0
      • UTF-16: 20 30
    • U+20AC EURO-ZEICHEN:
      • NR.: 8364
      • UTF-8: E2 82 AC
      • UTF-16: 20 AC
    • U+2122 MARKENZEICHEN:
      • NR.: 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ÄCHELNDES GESICHT:
      • NR.: 9786
      • UTF-8: E2 98 BA
      • UTF-16: 26 3A
    • U+2691 SCHWARZE FLAGGE:
      • 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 LATEINISCHES KREUZ:
      • Nº: 10014
      • UTF-8: E2 9C 9E
      • UTF-16: 27 1E
    • U+3020 POSTSTEMPEL GESICHT:
      • Nº: 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 EIN HAUFEN KACKE:
      • Nº: 128169
      • UTF-8: F0 9F 92 A9
      • UTF-16: D8 3D DC A9
    • U+1F680 RAKETE:
      • Nº: 128640
      • UTF-8: F0 9F 9A 80
      • UTF-16: D8 3D DE 80

Okay, ich lasse mich hinreißen...

Lustige Fakten:

0 Stimmen

En Code-Einheiten in UTF-16 sind 16 Bit breit. Sie haben sie mit einem Leerzeichen in der Mitte dargestellt, was irreführend ist. Die UTF-16-Darstellung für © sollte vielmehr lauten 00A9 anstelle von 00 A9 (das wäre dann UTF-16BE).

0 Stimmen

Was ist der Unterschied? Steht BE nicht für Big Endian? Er hat sie in Big Endian geschrieben, und eine in Big Endian UTF-16 geschriebene Datei wäre also dasselbe wie UTF-16BE, richtig?

10 Stimmen

Korrekturen: 1) ASCII hat 7 Bits, ein Byte hat 8 Bits, es ist also viel mehr als die Hälfte. 2) Unicode definiert, wie die Codepunkte zu kodieren sind. UTF-8, UTF-16 und UTF-32 sind im Unicode-Standard definiert.

36voto

Zimbabao Punkte 8054

Einfach gesprochen Unicode ist eine Norm, die allen Zeichen der Welt eine Nummer (genannt Code Point) zuweist (sie ist noch in Arbeit).

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

UTF-8 ist eine Multibyte-Zeichenkodierung. Die Zeichen können 1 bis 6 Bytes umfassen (einige davon sind im Moment nicht erforderlich).

UTF-32 jedes Zeichen hat 4 Bytes pro Zeichen.

UTF-16 verwendet 16 Bits für jedes Zeichen und stellt nur einen Teil der Unicode-Zeichen namens BMP dar (für alle praktischen Zwecke ist das ausreichend). Java verwendet diese Kodierung in seinen Zeichenketten.

12 Stimmen

Unicode ist ein 21-Bit-Codesatz und 4 Bytes reichen aus, um jedes Unicode-Zeichen in UTF-8 darzustellen. UTF-16 verwendet Surrogate, um Zeichen außerhalb der BMP (Basic Multilingual Plane) darzustellen; es benötigt entweder 2 oder 4 Bytes, um ein gültiges Unicode-Zeichen darzustellen. UCS-2 war die einzige 16-Bit-Variante von UTF-16 ohne Unterstützung für Surrogate oder Zeichen außerhalb der BMP.

1 Stimmen

Sie haben recht. UTF-8 hatte ursprünglich 6 Bytes, um ein 32-Bit unterzubringen. Ich wollte die Dinge eigentlich nicht zu sehr verkomplizieren, da er bereits mit dem Wiki-Dokument verwirrt war :)

3 Stimmen

Diese Antwort besagt, dass UTF-16 keine BMP-Codepunkte kodieren kann. Dies ist falsch, da diese genauso wie in UTF-8 mit Surrogatpaaren kodiert werden können. (Sie müssen an das veraltete UCS-2 denken, bevor Unicode 2.0 herauskam, das nur 16-Bit-Codepunkte kodierte). Außerdem verwendet Java nicht ganz UTF-16, sondern eine modifizierte Form davon, bei der der Codepunkt 0 anders kodiert wird.

23voto

John Punkte 6037

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 per Definition der letzte Unicode-Codepunkt, und er ist so definiert, weil er die technische Grenze von UTF-16 ist.

Es ist auch der größte Codepunkt, den UTF-8 in 4 Byte kodieren kann, aber die Idee hinter der UTF-8-Kodierung funktioniert auch für 5- und 6-Byte-Kodierungen, um Codepunkte bis 7FFFFFFF abzudecken, also die Hälfte dessen, was UTF-32 kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X