Von ASCII bis UTF-8 im Detail
UTF-8-Zeichenkodierung
Prinzip
Das Prinzip geht so: Die „normalen Zeichen” werden durch ein Byte dargestellt und die „ausgefalleneren” durch mehrere Bytes.
Die Zeichen des ASCII-Kodes werden exakt wie bei ASCII (und praktisch allen klassischen Kodierungen wie Latin‑1 etc.) mittels eines einzelnen Bytes dargestellt. Die Werte dieser Zeichen entsprechen genau dem ASCII-Standard. Damit kann ein Programm, welches UTF‑8 verarbeitet, auch ganz normale ASCII-Dateien und -Zeichenketten lesen und schreiben. Wir sind also voll ASCII-kompatibel.
Wieviel Byte gelten diesem Zeichen?
Wenn manche Zeichen durch ein Byte, andere durch zwei oder mehr Byte repräsentiert werden, muss ein Programm zur Datenverarbeitung bestimmen können, wann ein Zeichen endet und ein neues anfängt. Dazu benutzt UTF‑8 folgenden Algorithmus:
- Wenn ein Byte einen Zahlenwert zwischen 0 und 127 (0x7F) verkörpert, dann handelt es sich um ein Zeichen, welches durch nur ein Byte repräsentiert wird. Das Byte steht für das Zeichen gemäß ASCII-Standard.
- Wenn ein Byte einen Zahlenwert zwischen 192 (0xC0) und 223 (0xDF) hat, dann ist es das erste Byte eines durch zwei Byte repäsentierten Zeichens. Das heißt, dass das folgende Byte auch noch zu diesem Zeichen gehört.
- Liegt der Zahlenwert eines Bytes zwischen 224 (0xE0) und 239 (0xEF), so läutet es ein durch drei Byte repräsentiertes Zeichen ein. Also sind für die Interpretation als Zeichen dieses und die nächsten beiden Byte zu berücksichtigen.
- Entsprechend gibt es auch einen Bereich für Zeichen, die durch vier Bytes repräsentiert werden - und (theoretisch) darüberhinaus.
Einschub für Detailverliebte und Binär-Liebhaber:
Die Kodierung verwendet hinter den Kulissen noch ein paar weitere
Regeln, um das ganze robust zu machen. Während die Start-Bytes,
entsprechend der oben angegebenen Zahlenwerte, mit den Binärsquenzen
0, 110, 1110 oder 11110 (für 1-, 2-, 3-, 4-Byte-Zeichen) beginnen,
haben Folge-Bytes immer die Binärsequenz 10 an ihrem Anfang.
So sind nicht nur die Bereiche einfach nachvollziehbar abgegrenzt,
sondern man weiß von einem Byte stets, ob es der Anfang eines Zeichens
oder ein Folgebyte ist.
Entsprechend braucht UTF-8 nur für spezielle Zeichen außerhalb des ASCII-Zeichensatzes mehrere Bytes. Ein Text mit 1000 Buchstaben des englischen Alphabets, wird genau 1000 Bytes vereinnahmen. Kommt darin ein einzelnes Zwei-Byte-Zeichen vor (nehmen wir das scharfe S), so wird der Text 1001 Byte lang sein: 999 Zeichen werden durch je ein Byte dargestellt und für das scharfe S werden zwei benötigt.
Zum Vergleich wäre die gleiche Datei bei UTF-16-Kodierung jeweils 2000 Byte groß - davon 1000 bzw. 999 Nullen. Bei UTF‑32 wären es sogar 4000 Byte, wovon wiederum 3000 bzw. 2999 Stellen nur durch Nullen gefüllt wären.
Vorteile
- Die Dateien werden nicht größer als nötig.
- Alle Zeichen des Unicode-Zeichensatzes können kodiert werden.
- UTF-8 ist voll ASCII-kompatibel.
Jetzt mal konkret und anschaulich
Mit meinem kleinen Textinspector kann man sich für einen kurzen Text anzeigen lassen, welche Unicode-Punkte er enthält und wie diese in UTF-8 kodiert werden.
Das sollte dann auch vor Augen führen, dass es bei Zeichen verschiedene Aspekte gibt, die voneinander zu unterscheiden sind. Um zu zeigen, dass Unicode erweiterbar ist, betrachten wir mal ein relativ junges Zeichen, nämlich das scharfe S als Großbuchstaben. Bereits 2008 - neun Jahre, bevor der Rat für Deutsche Rechtschreibung sich auf die Einführung des großen scharfen S einigen konnte - hat das Unicode-Consortium den Buchstaben bereits kodiert.
Wir haben jetzt also folgende Aspekte, die man fein auseinanderhalten muss:
-
Der Name des Zeichens. Unabhängig von seinem genauen Aussehen hat jedes
Zeichen einen Namen, hier:
LATIN CAPITAL LETTER SHARP S (Großes scharfes S) -
Die „Glyphe”, also das Aussehen des Zeichens. Das hängt dann wiederum
von der Schriftart ab. Für jedes Zeichen gibt es also veschiedene
Glyphen. In der Schriftart dieser Web-Seite sieht das große
scharte S so aus:
ẞ (Etwas breiter als „ß”, der Kleinbuchstabe.) -
Der Unicode-Punkt (Codepoint), also praktisch die Nummer, die das
Zeichen beim durchnummerieren erhalten hat. Für das große scharfe
S wurde die noch freie Nummer 7838 wohl als passend angesehen.
Als hexadezimale Zahl (übliche Bezeichnung bei Unicode-Punkten)
ist das:
1E9E
-
Die UTF-8-Kodierung, d.h. die Zahlenwerte, die in UTF-8 ebendieses
Zeichen repräsentieren. Man könnte jetzt denken: Warum nicht auch 7838?
Um die Antwort kurz zu halten: Weil die Anzahl der Bytes in UTF-8
flexibel ist, kann man nicht einfach alle Zahlenwerte der Reihe nach
nehmen. Lassen wir das mal so stehen. Das große scharfe S wird durch
drei Bytes mit den Zahlenwerten 30, 186 und 158 repräsentiert. So
schwirrt es also durch den Computer und wird so in Dateien
geschrieben. In hexadezimale Werte umgewandelt ist damit unser
großes scharfes S:
E1 BA 9E
Damit sind die wichtigsten Punkte zum Thema Unicode im Allgemeinen und UTF-8 im Speziellen dargelegt. Im folgenden Teil 8 wird noch kurz auf die Byte-Order-Mark eingegangen, die aber in vielen Bereichen (z.B. im Web) höchstens als Fehlerquelle auftritt.