4. Syntax von UTF-8-Byte-Sequenzen (Syntax of UTF-8 Byte Sequences)
Zur Bequemlichkeit von Implementierern, die ABNF verwenden, wird hier eine Definition von UTF-8 in ABNF-Syntax gegeben.
UTF-8-Zeichenfolgen-Definition (UTF-8 String Definition)
Eine UTF-8-Zeichenfolge ist eine Sequenz von Bytes, die eine Sequenz von UCS-Zeichen darstellt. Eine Byte-Sequenz ist nur dann gültiges UTF-8, wenn sie mit der folgenden Syntax übereinstimmt, die von den UTF-8-Kodierungsregeln abgeleitet ist und im ABNF von [RFC2234] ausgedrückt wird.
ABNF-Syntax
UTF8-octets = *( UTF8-char )
UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
UTF8-1 = %x00-7F
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
%xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
%xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF
Syntaxerklärung (Syntax Explanation)
UTF8-1: Ein-Byte-Sequenzen
%x00-7F
- Bereich: 0x00 bis 0x7F (0-127)
- Kodierung: Vollständiger ASCII-Bereich
- Muster:
0xxxxxxx
UTF8-2: Zwei-Byte-Sequenzen
%xC2-DF UTF8-tail
- Erstes Byte: 0xC2 bis 0xDF (194-223)
- Folgebyte: 0x80 bis 0xBF (128-191)
- Muster:
110xxxxx 10xxxxxx - Hinweis: Das erste Byte kann nicht 0xC0 oder 0xC1 sein (würde überlange Kodierung erzeugen)
UTF8-3: Drei-Byte-Sequenzen
Vier Fälle:
Fall 1: %xE0 %xA0-BF UTF8-tail
- Erstes Byte: 0xE0
- Zweites Byte: 0xA0 bis 0xBF
- Drittes Byte: 0x80 bis 0xBF
- Kodierungsbereich: U+0800 bis U+0FFF
Fall 2: %xE1-EC 2( UTF8-tail )
- Erstes Byte: 0xE1 bis 0xEC
- Folgende Bytes: Zwei UTF8-tail (0x80-0xBF)
- Kodierungsbereich: U+1000 bis U+CFFF
Fall 3: %xED %x80-9F UTF8-tail
- Erstes Byte: 0xED
- Zweites Byte: 0x80 bis 0x9F
- Drittes Byte: 0x80 bis 0xBF
- Kodierungsbereich: U+D000 bis U+D7FF
- Hinweis: Vermeidet den Ersatzpaar-Bereich (U+D800-U+DFFF)
Fall 4: %xEE-EF 2( UTF8-tail )
- Erstes Byte: 0xEE bis 0xEF
- Folgende Bytes: Zwei UTF8-tail
- Kodierungsbereich: U+E000 bis U+FFFF
UTF8-4: Vier-Byte-Sequenzen
Drei Fälle:
Fall 1: %xF0 %x90-BF 2( UTF8-tail )
- Erstes Byte: 0xF0
- Zweites Byte: 0x90 bis 0xBF
- Folgende Bytes: Zwei UTF8-tail
- Kodierungsbereich: U+10000 bis U+3FFFF
Fall 2: %xF1-F3 3( UTF8-tail )
- Erstes Byte: 0xF1 bis 0xF3
- Folgende Bytes: Drei UTF8-tail
- Kodierungsbereich: U+40000 bis U+FFFFF
Fall 3: %xF4 %x80-8F 2( UTF8-tail )
- Erstes Byte: 0xF4
- Zweites Byte: 0x80 bis 0x8F
- Folgende Bytes: Zwei UTF8-tail
- Kodierungsbereich: U+100000 bis U+10FFFF
Ungültige Byte-Werte (Invalid Byte Values)
Die folgenden Byte-Werte erscheinen niemals in gültigen UTF-8-Sequenzen:
Verbotene Byte-Werte:
- 0xC0, 0xC1 (würden überlange 2-Byte-Sequenzen erzeugen)
- 0xF5 - 0xFF (über den Unicode-Bereich hinaus)
Verbotene Muster
Die ABNF-Grammatik schließt bestimmte Byte-Sequenzen explizit aus:
-
Überlange Kodierungen:
- 0xC0, 0xC1 (würden überlange 2-Byte-Sequenzen erzeugen)
- 0xE0 gefolgt von 0x80-0x9F (würden überlange 3-Byte-Sequenzen erzeugen)
- 0xF0 gefolgt von 0x80-0x8F (würden überlange 4-Byte-Sequenzen erzeugen)
-
Ersatzzeichenpaare (U+D800 bis U+DFFF):
- 0xED gefolgt von 0xA0-0xBF
-
Über Unicode hinaus (> U+10FFFF):
- 0xF4 gefolgt von 0x90-0xBF
- 0xF5-0xFF (alle Sequenzen, die mit diesen Bytes beginnen)
Referenztabelle
| Bytebereich | UTF-8-Typ | Gültiges Muster | Kodierter Unicode-Bereich |
|---|---|---|---|
| 0x00-0x7F | UTF8-1 | 0xxxxxxx | U+0000 bis U+007F |
| 0xC2-0xDF | UTF8-2 | 110xxxxx 10xxxxxx | U+0080 bis U+07FF |
| 0xE0-0xEF | UTF8-3 | 1110xxxx 10xxxxxx 10xxxxxx | U+0800 bis U+FFFF |
| 0xF0-0xF4 | UTF8-4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | U+10000 bis U+10FFFF |
Validierungsschritte
Für jedes zu validierende Byte:
- Bestimmen Sie den Sequenztyp anhand des ersten Bytes
- Überprüfen Sie die Sequenzlänge (genügend verbleibende Bytes)
- Validieren Sie jedes Folgebyte im Bereich 0x80-0xBF
- Überprüfen Sie auf verbotene Muster (überlange Kodierungen, Ersatzzeichen, Überschreitungen)
- Fahren Sie mit dem nächsten Zeichen fort
Validierungsbeispiele
Gültige Sequenzen
Beispiel 1: 0x41
Prüfung: 0x41 in [0x00-0x7F] → UTF8-1 → ✅ Gültig
Zeichen: 'A'
Beispiel 2: 0xC2 0xA9
Prüfung: 0xC2 in [0xC2-0xDF], 0xA9 in [0x80-0xBF] → UTF8-2 → ✅ Gültig
Zeichen: '©'
Beispiel 3: 0xE4 0xBD 0xA0
Prüfung: 0xE4 in [0xE1-0xEC], nächste zwei Bytes in [0x80-0xBF] → UTF8-3 → ✅ Gültig
Zeichen: '你'
Beispiel 4: 0xF0 0x9F 0x98 0x80
Prüfung: 0xF0 gefolgt von 0x9F in [0x90-0xBF], nächste zwei Bytes in [0x80-0xBF] → UTF8-4 → ✅ Gültig
Zeichen: '😀'
Ungültige Sequenzen
Beispiel 1: 0xC0 0x80
Problem: 0xC0 ist verboten → ❌ Ungültig (überlange Kodierung)
Beispiel 2: 0xED 0xA0 0x80
Problem: 0xED gefolgt von 0xA0 nicht in [0x80-0x9F] → ❌ Ungültig (Ersatzzeichenpaar-Bereich)
Beispiel 3: 0xF5 0x80 0x80 0x80
Problem: 0xF5 ist verboten → ❌ Ungültig (jenseits des Unicode-Bereichs)
Beispiel 4: 0xE4 0xBD
Problem: 3-Byte-Sequenz unvollständig → ❌ Ungültig (abgeschnitten)
⚠️ Wichtiger Hinweis
HINWEIS -- Die autoritative Definition von UTF-8 findet sich in [UNICODE]. Diese Grammatik soll dasselbe beschreiben, was Unicode beschreibt, erhebt jedoch keinen Anspruch auf Autorität. Implementierer werden aufgefordert, sich auf die autoritative Quelle zu verlassen, anstatt auf dieses ABNF.
Implementierungsvorschlag
Validierungsalgorithmus-Pseudocode
def is_valid_utf8(bytes):
i = 0
while i < len(bytes):
b = bytes[i]
if b <= 0x7F: # UTF8-1
i += 1
elif 0xC2 <= b <= 0xDF: # UTF8-2
if i + 1 >= len(bytes) or not (0x80 <= bytes[i+1] <= 0xBF):
return False
i += 2
elif b == 0xE0: # UTF8-3 Fall 1
if i + 2 >= len(bytes):
return False
if not (0xA0 <= bytes[i+1] <= 0xBF and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif 0xE1 <= b <= 0xEC: # UTF8-3 Fall 2
if i + 2 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0xBF and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif b == 0xED: # UTF8-3 Fall 3
if i + 2 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0x9F and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif 0xEE <= b <= 0xEF: # UTF8-3 Fall 4
if i + 2 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0xBF and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif b == 0xF0: # UTF8-4 Fall 1
if i + 3 >= len(bytes):
return False
if not (0x90 <= bytes[i+1] <= 0xBF and
0x80 <= bytes[i+2] <= 0xBF and
0x80 <= bytes[i+3] <= 0xBF):
return False
i += 4
elif 0xF1 <= b <= 0xF3: # UTF8-4 Fall 2
if i + 3 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0xBF and
0x80 <= bytes[i+2] <= 0xBF and
0x80 <= bytes[i+3] <= 0xBF):
return False
i += 4
elif b == 0xF4: # UTF8-4 Fall 3
if i + 3 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0x8F and
0x80 <= bytes[i+2] <= 0xBF and
0x80 <= bytes[i+3] <= 0xBF):
return False
i += 4
else:
return False # Ungültiges Byte
return True
Verwandte Links
- Zurück: 3. UTF-8-Definition (UTF-8 definition)
- Zurück zur RFC 3629 Startseite
- Weiter: 5. Versionen der Standards (Versions of the standards)