UTF-8

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

UTF-8 (Abk. für 8-Bit UCS Transformation Format, wobei UCS wiederum Universal Character Set abkürzt) ist die am weitesten verbreitete Kodierung für Unicode-Zeichen (Unicode und UCS sind praktisch identisch). Die Kodierung wurde im September 1992 von Ken Thompson und Rob Pike bei Arbeiten an dem Plan-9-Betriebssystem festgelegt. Die Kodierung wurde zunächst im Rahmen von X/Open als FSS-UTF (filesystem safe UTF in Abgrenzung zu UTF-1, das diese Eigenschaft nicht hat) bezeichnet, in den Folgejahren erfolgte im Rahmen der Standardisierung die Umbenennung auf die heute übliche Bezeichnung UTF-8.[1]

UTF-8 ist in den ersten 128 Zeichen (Indizes 0–127) deckungsgleich mit ASCII und eignet sich mit i. d. R. nur einem Byte Speicherbedarf für Zeichen vieler westlicher Sprachen besonders für die Kodierung englischsprachiger Texte, die sich im Regelfall ohne Modifikation daher sogar mit nicht-UTF-8-fähigen Texteditoren ohne Beeinträchtigung bearbeiten lassen, was einen der Gründe für den Status als De-facto-Standard-Zeichenkodierung des Internets und damit verbundener Dokumenttypen darstellt. Im Juni 2014 verwenden 81,1 % aller Websites UTF-8.[2]

In anderen Sprachen ist der Speicherbedarf in Byte pro Zeichen größer, wenn diese vom ASCII-Zeichensatz abweichen: Bereits die deutschen Umlaute erfordern zwei Byte; kyrillische, fernöstliche und Sprachen aus dem afrikanischen Raum belegen bis zu 4 Byte je Zeichen. Da die Verarbeitung von UTF-8 als Multibyte-Zeichenfolge wegen der notwendigen Analyse jedes Bytes im Vergleich zu Zeichenkodierungen mit fester Byteanzahl je Zeichen mehr Rechenaufwand und für bestimmte Sprachen auch mehr Speicherplatz erfordert, werden abhängig vom Einsatzszenario auch andere UTF-Kodierungen zur Abbildung von UNICODE-Zeichensätzen verwendet: Microsoft Windows als meistgenutztes Desktop-Betriebssystem verwendet intern als Kompromiss zwischen UTF-8 und UTF-32 etwa UTF-16 Little Endian.

Allgemeines[Bearbeiten]

Bei der UTF-8-Kodierung wird jedem Unicode-Zeichen eine speziell kodierte Zeichenkette variabler Länge zugeordnet. Dabei unterstützt UTF-8 Zeichenketten bis zu einer Länge von vier Byte, auf die sich – wie bei allen UTF-Formaten – alle Unicode-Zeichen abbilden lassen.

UTF-8 hat eine zentrale Bedeutung als globale Zeichenkodierung im Internet. Die Internet Engineering Task Force verlangt von allen neuen Internetkommunikationsprotokollen, dass die Zeichenkodierung deklariert wird und dass UTF-8 eine der unterstützten Kodierungen ist. Das Internet Mail Consortium (IMC) empfiehlt, dass alle E-Mail-Programme UTF-8 darstellen und senden können.[3] Im Jahr 2008 wurde diese Empfehlung allerdings immer noch nicht global befolgt.

Auch bei der in Webbrowsern angewendeten Auszeichnungssprache HTML setzt sich UTF-8 zur Darstellung sprachspezifischer Zeichen zunehmend durch und ersetzt dabei die vorher genutzten HTML-Entitäten.[4]

Eigenschaften[Bearbeiten]

  • Multi-Byte-Zeichenkodierung (MBCS) ähnlich CP950/CP936/CP932(chinesisch/japanisch), aber ohne die (damals wichtige und nützliche) Eigenschaft, dass doppelt breit dargestellte Zeichen zwei Bytes lang sind
  • 7-Bit-ASCII ist gleichzeitig UTF-8 und hochgradig kompatibel zu bisherigen 8-Bit-Zeichensätzen
  • Trail-Bytes sind niemals 7-Bit-ASCII-Zeichen (ermöglicht Verarbeitung und Parsen mit üblichen 7-Bit-Zeichenkonstanten)
  • Relativ kompakt, besonders bei europäischen Zeichen, etwas weniger bei (bspw.) chinesischen Zeichen in höheren Kodepositionen, häufig deutlich kompakter als UTF-16 (Windows)
  • Sortierbarkeit bleibt erhalten, zwei UTF-8-Zeichenketten haben dieselbe Sortierreihenfolge wie zwei unkodierte Unicode-Zeichenketten
  • In beiden Richtungen durchsuchbar (bei bisherigen MBCS nicht der Fall)
  • Einfache Transkodierungsfunktion (zudem leicht hardware-implementierbar)
  • Reichlich Kodierungs-Reserve (falls sich am Unicode-Standard doch noch etwas ändert)

Normung[Bearbeiten]

UTF-8 ist von der IETF, dem Unicode Consortium und der ISO gegenwärtig identisch definiert in den Normdokumenten:

  • RFC 3629 / STD 63 (2003)
  • The Unicode Standard, Version 4.0, §3.9–§3.10 (2003)
  • ISO/IEC 10646-1:2000 Annex D (2000)

Diese lösen ältere, teilweise abweichende Definitionen ab, die teilweise noch von älterer Software benutzt werden:

  • ISO/IEC 10646-1:1993 Amendment 2 / Annex R (1996)
  • The Unicode Standard, Version 2.0, Appendix A (1996)
  • RFC 2044 (1996)
  • RFC 2279 (1998)
  • The Unicode Standard, Version 3.0, §2.3 (2000) und Corrigendum #1: UTF-8 Shortest Form (2000)
  • Unicode Standard Annex #27: Unicode 3.1 (2001)

Kodierung[Bearbeiten]

Unicode-Zeichen mit den Werten aus dem Bereich von 0 bis 127 (0 bis 7F hexadezimal) werden in der UTF-8-Kodierung als ein Byte mit dem gleichen Wert wiedergegeben. Daher sind alle Daten, für die ausschließlich echte ASCII-Zeichen verwendet werden, in beiden Darstellungen identisch.

Unicode-Zeichen größer als 127 werden in der UTF-8-Kodierung zu Byteketten der Länge zwei bis vier kodiert.

Unicode-Bereich (hexadezimal) UTF-8-Kodierung (binär) Bemerkungen Möglichkeiten (theoretisch)
0000 0000 – 0000 007F 0xxxxxxx In diesem Bereich (128 Zeichen) entspricht UTF-8 genau dem ASCII-Code: Das höchste Bit ist 0, die restliche 7-Bit-Kombination ist das ASCII-Zeichen. 27 128
0000 0080 – 0000 07FF 110xxxxx 10xxxxxx Das erste Byte beginnt immer mit 11, die folgenden Bytes mit 10. Die xxxxx stehen für die Bits des Unicode-Zeichenwerts. Dabei wird das niederwertigste Bit des Zeichenwerts auf das rechte x im letzten Byte abgebildet, die höherwertigen Bits fortschreitend von rechts nach links. Die Anzahl der Einsen vor der ersten 0 im ersten Byte ist gleich der Gesamtzahl der Bytes für das Zeichen. (In Klammern jeweils die theoretisch maximal möglichen.) 211 − 27
(211)
1920
(2048)
0000 0800 – 0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 216 − 211
(216)
63.488
(65.536)
0001 0000 – 0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 220
(221)
1.048.576
(2.097.152)

Der Algorithmus lässt theoretisch bis zu acht Bytes lange Byteketten und dadurch über vier Billionen Zeichen zu. Die letzte Stufe enthielt als erstes Byte 11111111 und danach sieben Folge-Bytes mit jeweils sechs Nutz-Bits. Die gesamte Codefolge wäre dann 2(7*6) = 242 = 4.398.046.511.104 Zeichen). Real definiert wurde ursprünglich eine Folge aus einem ersten Byte mit bis zu 1111110x und somit fünf Folge-Bytes der Form 10xxxxxx, also zusammen sechs Byte mit insgesamt 31 Bit für den enthaltenen Unicode-Wert. In seiner Verwendung als UTF-Kodierung ist er aber auf den gemeinsamen Coderaum aller Unicode-Kodierungen beschränkt, also von 0 bis 0010 FFFF (1.114.112 Möglichkeiten) und weist maximal vier Bytes lange Byteketten auf. Der damit verfügbare Wertebereich für den Zeichencode wird letztlich nicht vollständig benutzt. Entsprechend lange Bytefolgen und große Werte gelten heute als unzulässige Codes und sind entsprechend zu behandeln.

Das erste Byte eines UTF-8-kodierten Zeichens nennt man dabei Start-Byte, weitere Bytes heißen Folge-Bytes. Start-Bytes beginnen also immer mit 0 oder 11, Folge-Bytes immer mit 10.

  • Ist das höchste Bit des ersten Bytes 0, handelt es sich um ein ASCII-Zeichen, da ASCII eine 7-Bit-Kodierung ist und die ersten 128 Unicode-Zeichen den ASCII-Zeichen entsprechen. Damit sind alle ASCII-Zeichenketten automatisch aufwärtskompatibel zu UTF-8.
  • Ist das höchste Bit des ersten Bytes 1, handelt es sich um ein Mehrbytezeichen, also ein Unicode-Zeichen mit einer Zeichennummer größer als 127.
  • Sind die höchsten beiden Bits eines Bytes 11, handelt es sich um das Startbyte eines Mehrbytezeichens, sind sie 10, um ein Folgebyte.
  • Die lexikalische Ordnung nach Bytewerten entspricht der lexikalischen Ordnung nach Zeichennummern, da höhere Zeichennummern mit entsprechend mehr 1-Bits im Start-Byte kodiert werden.
  • Bei den Startbytes von Mehrbyte-Zeichen gibt die Anzahl der höchsten 1-Bits die gesamte Bytezahl des als Mehrbyte-Zeichen kodierten Unicode-Zeichens an. Anders interpretiert, die Anzahl der 1-Bits links des höchsten 0-Bits entspricht der Anzahl an Folgebytes plus eins, z. B. 1110xxxx 10xxxxxx 10xxxxxx = drei Bits vor dem höchsten 0-Bit = drei Bytes insgesamt, zwei Bits nach dem höchsten 1-Bit vor dem höchsten 0-Bit = zwei Folgebytes.
  • Startbytes (0… oder 11…) und Folgebytes (10…) lassen sich eindeutig voneinander unterscheiden. Somit kann ein Bytestrom auch in der Mitte gelesen werden, ohne dass es Probleme mit der Dekodierung gibt, was insbesondere bei der Wiederherstellung defekter Daten wichtig ist. Bytes beginnend mit 10 werden einfach übersprungen, bis 0… oder 11… erkannt wird. Dass Startbytes und Folgebytes eindeutig voneinander unterschieden sind, ist ein Vorteil der UTF-8 Kodierung. Bei Kodierungen ohne diese Eigenschaft ist das Lesen eines Datenstroms, dessen Beginn unbekannt ist, unter Umständen nicht möglich.

Zu beachten:

  • Das gleiche Zeichen kann theoretisch auf verschiedene Weise kodiert werden (Zum Beispiel „a“ als 01100001 oder fälschlich als 11000001 10100001). Jedoch ist nur die jeweils kürzestmögliche Kodierung erlaubt. Dieser Umstand hat mehrfach zu Problemen geführt, indem Programme bei ungültigen Kodierungen abstürzen, diese als gültig interpretieren oder einfach ignorieren. Die Kombinationen der letzten beiden Verhaltensweisen führte z. B. zu Firewalls, die gefährliche Inhalte auf Grund der ungültigen Kodierung nicht erkennen, der zu schützende Client diese Kodierungen jedoch als gültig interpretiert und dadurch gefährdet ist.
  • Bei mehreren Bytes für ein Zeichen werden die Bits bündig angeordnet – das niedrigste Bit (least significant bit) des Unicode-Zeichens steht also immer im niedrigsten Bit des letzten UTF-8-Bytes.
  • Ursprünglich gab es auch Kodierungen mit mehr als vier Oktetten (bis zu sechs), diese sind jedoch ausgeschlossen worden, da es in Unicode keine korrespondierenden Zeichen gibt und ISO 10646 in seinem möglichen Zeichenumfang an Unicode angeglichen wurde.
  • Für alle auf dem lateinischen Alphabet basierenden Schriften ist UTF-8 eine besonders platzsparende Methode zur Abbildung von Unicode-Zeichen.
  • Die Unicodebereiche U+D800–U+DBFF und U+DC00–U+DFFF sind ausdrücklich keine Zeichen, sondern dienen nur in UTF-16 zur Kodierung von Zeichen außerhalb der Basic Multilingual Plane, sie wurden früher als Low und High surrogates bezeichnet. Folglich sind Bytefolgen, die diesen Bereichen entsprechen, kein gültiges UTF-8. Zum Beispiel wird U+10400 in UTF-16 als D801,DC00 dargestellt, sollte in UTF-8 aber als F0,90,90,80 und nicht als ED,A0,81,ED,B0,80 ausgedrückt werden. Java unterstützt dies seit der Version 1.5.[5] Aufgrund der weiten Verbreitung der falschen Kodierung, insbesondere auch in Datenbanken, wurde diese Kodierung nachträglich als CESU-8 normiert.
  • In UTF-8, UTF-16 und UTF-32 ist der gesamte Wertebereich von Unicode kodiert.

Durch die Kodierungsregel von UTF-8 sind bestimmte Bytes nicht zulässig. In nachfolgender Tabelle sind alle 256 Möglichkeiten zusammengefasst und deren Verwendung bzw. Gültigkeit angegeben. Bytes in roten Zeilen sind unzulässig, grün beschreibt zulässige Bytes, welche unmittelbar ein Zeichen darstellen. In blau sind jene Werte hinterlegt, welche den Start einer Sequenz von zwei oder mehr Byte beginnen und als Sequenz mit den Bytes aus orange hinterlegten Zeilen fortgesetzt werden.

UTF-8 Wertebereich Bedeutung
Binär Hexadezimal Dezimal
0000000001111111 007F 0127 Ein-Byte lange Zeichen, deckungsgleich mit US-ASCII.
1000000010111111 80BF 128191 Zweites, drittes oder viertes Byte einer Bytesequenz.
1100000011000001 C0C1 192193 Start einer 2 Byte langen Sequenz, welche den Codebereich aus 0 bis 127 abbildet, unzulässig
1100001011011111 C2DF 194223 Start einer 2 Byte langen Sequenz (U+0080 … U+07FF)
Startbyte abgedeckter Codebereich
C2 U+0080 … U+00BF
C3 U+00C0 … U+00FF
C4 U+0100 … U+013F
C5 U+0140 … U+017F
C6 U+0180 … U+01BF
C7 U+01C0 … U+01FF
C8 U+0200 … U+023F
C9 U+0240 … U+027F
CA U+0280 … U+02BF
CB U+02C0 … U+02FF
CC U+0300 … U+033F
CD U+0340 … U+027F
CE U+0380 … U+03BF
CF U+03C0 … U+03FF
D0 U+0400 … U+043F
D1 U+0440 … U+047F
D2 U+0480 … U+04BF
D3 U+04C0 … U+04FF
D4 U+0500 … U+053F
D5 U+0540 … U+057F
D6 U+0580 … U+05BF
D7 U+05C0 … U+05FF
D8 U+0600 … U+063F
D9 U+0640 … U+067F
DA U+0680 … U+06BF
DB U+06C0 … U+06FF
DC U+0700 … U+073F
DD U+0740 … U+077F
DE U+0780 … U+07BF
DF U+07C0 … U+07FF
1110000011101111 E0EF 224239 Start einer 3 Byte langen Sequenz (U+0800 … U+FFFF)
Startbyte abgedeckter Codebereich
E0 U+0800 … U+0FFF (2. Byte muss aus Bereich A0 … BF sein!)
E1 U+1000 … U+1FFF
E2 U+2000 … U+2FFF
E3 U+3000 … U+3FFF
E4 U+4000 … U+4FFF
E5 U+5000 … U+5FFF
E6 U+6000 … U+6FFF
E7 U+7000 … U+7FFF
E8 U+8000 … U+8FFF
E9 U+9000 … U+9FFF
EA U+A000 … U+AFFF
EB U+B000 … U+BFFF
EC U+C000 … U+CFFF
ED U+D000 … U+DFFF (2. Byte muss im Bereich 80 … 9F sein!)
EE U+E000 … U+EFFF (Private Use Zone)
EF U+F000 … U+FFFF (Private Use Zone, wenn 2. Byte im Bereich 80 … A3)
1111000011110100 F0F4 240244 Start einer 4 Byte langen Sequenz (Inklusive der ungültigen Codebereiche von 110000 bis 13FFFF)
Startbyte abgedeckter Codebereich
F0 U+10000 … U+3FFFF (2. Byte muss aus Bereich 90 … BF sein!)
F1 U+40000 … U+7FFFF
F2 U+80000 … U+BFFFF
F3 U+C0000 … U+FFFFF
F4 U+100000 … U+10FFFF (2. Byte muss aus Bereich 80 … 8F sein!)
1111010111110111 F5F7 245247 Ungültig nach RFC 3629: Start einer 4 Byte langen Sequenz für Codebereich über 140000
1111100011111011 F8FB 248251 Ungültig nach RFC 3629: Start einer 5 Byte langen Sequenz
1111110011111101 FCFD 252253 Ungültig nach RFC 3629: Start einer 6 Byte langen Sequenz
1111111011111111 FEFF 254255 Ungültig. In der ursprünglichen UTF-8-Spezifikation nicht definiert.
Code …0 …1 …2 …3 …4 …5 …6 …7 …8 …9 …A …B …C …D …E …F
0… NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
1… DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
2… SP ! " # $ % & ' ( ) * + , - . /
3… 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4… @ A B C D E F G H I J K L M N O
5… P Q R S T U V W X Y Z [ \ ] ^ _
6… ` a b c d e f g h i j k l m n o
7… p q r s t u v w x y z { | } ~ DEL
8… Zweites, drittes oder viertes Byte einer Bytesequenz.
9…
A…
B…
C… Start einer 2 Byte langen Sequenz.
D…
E… Start einer 3 Byte langen Sequenz.
F… Start einer 4 Byte langen Sequenz.
…0 …1 …2 …3 …4 …5 …6 …7 …8 …9 …A …B …C …D …E …F

In folgender Tabelle sind einige Kodierungsbeispiele für UTF-8 angegeben:

Beispiele für UTF-8 Kodierungen
Zeichen Unicode Unicode binär UTF-8 binär UTF-8 hexadezimal
Buchstabe y U+0079 00000000 01111001 01111001 79
Buchstabe ä U+00E4 00000000 11100100 11000011 10100100 C3 A4
Zeichen für eingetragene Marke ® U+00AE 00000000 10101110 11000010 10101110 C2 AE
Eurozeichen U+20AC 00100000 10101100 11100010 10000010 10101100 E2 82 AC
Violinschlüssel 𝄞 U+1D11E 00000001 11010001 00011110 11110000 10011101 10000100 10011110 F0 9D 84 9E

Das letzte Beispiel liegt außerhalb des ursprünglich in Unicode (unter Version 2.0) enthaltenen Codebereiches (16 Bit), der in der aktuellen Unicode-Version als BMP-Bereich (Ebene 0) enthalten ist. Da derzeit viele Schriftarten diese neuen Unicode-Bereiche noch nicht enthalten, können die dort enthaltenen Zeichen auf vielen Plattformen nicht korrekt dargestellt werden. Stattdessen wird ein Ersatzzeichen dargestellt, welches als Platzhalter dient.

Darstellung in Editoren[Bearbeiten]

Byte Order Mark[Bearbeiten]

Obwohl bei UTF-8 aufgrund der Art der Kodierung grundsätzlich nicht das Problem unterschiedlicher Bytereihenfolgen auftreten kann, fügen einige Programme eine Byte Order Mark (BOM, deutsch Bytereihenfolge-Markierung) am Dateianfang von UTF-8-Dateien ein. Die BOM besteht aus der Bytesequenz EF BB BF, die in nicht UTF-8-fähigen Texteditoren und Browsern meist als ISO-8859-1-Zeichenfolge  erscheint und für Kompatibilitätsprobleme verantwortlich sein kann.

Nicht im Unicodeblock Basis-Lateinisch enthaltene Zeichen[Bearbeiten]

Buchstaben des englischen Alphabets werden in UTF-8 und ISO-8859 identisch angezeigt. Probleme treten bei den anderen Zeichen auf, beispielsweise bei Umlauten.

Ein Beispiel für das Wort Höhe:

UTF-8-Text in ISO-8859-Umgebung
Höhe -> Höhe. In UTF-8 besteht das Zeichen ö aus zwei Bytes, die in ISO-8859-1 den Zeichen à und entsprechen.
ISO-8859-Text in UTF-8-Umgebung
Höhe -> H0xF6he bzw. Fehlermeldung mit Abbruch. Ein Byte mit dem Hexadezimalwert F6 ist in UTF-8 nicht zulässig.

Quellen[Bearbeiten]

  1. RFC 3629, Kapitel 1 (Introduction), engl.
  2. http://w3techs.com/technologies/history_overview/character_encoding
  3. Using International Characters in Internet Mail (englisch) – Seite beim Internet Mail Consortium, vom 1. August 1998 (abgerufen am: 12. Juli 2012)
  4. Usage of character encodings for websites (englisch) – Übersichtsseite bei W3Techs, Stand: 14. März 2012 (abgerufen am: 12. Juli 2012)
  5. Supplementary Characters in the Java Platform

Weblinks[Bearbeiten]

 Wiktionary: UTF-8 – Bedeutungserklärungen, Wortherkunft, Synonyme, Übersetzungen