RFC 3629 - UTF-8, ein Transformationsformat von ISO 10646
- Status: Internet Standard
- Veröffentlicht: November 2003
- Stream: IETF
- Ersetzt: RFC2279
- Errata: Keine Errata
Zusammenfassung (Abstract)
ISO/IEC 10646-1 definiert einen großen Zeichensatz namens Universal Character Set (UCS), der die meisten Schriftsysteme der Welt umfasst. Die ursprünglich vorgeschlagenen Kodierungen des UCS waren jedoch nicht mit vielen aktuellen Anwendungen und Protokollen kompatibel, was zur Entwicklung von UTF-8, dem Gegenstand dieses Memos, geführt hat. UTF-8 hat die Eigenschaft, den vollständigen US-ASCII-Bereich zu bewahren und damit Kompatibilität mit Dateisystemen, Parsern und anderer Software zu bieten, die auf US-ASCII-Werte angewiesen ist, aber für andere Werte transparent ist. Dieses Memo macht RFC 2279 obsolet und ersetzt es.
Status dieses Memos (Status of this Memo)
Dieses Dokument spezifiziert ein Internet Standards Track-Protokoll für die Internet-Community und bittet um Diskussion und Verbesserungsvorschläge. Bitte beziehen Sie sich auf die aktuelle Ausgabe der „Internet Official Protocol Standards" (STD 1) für den Standardisierungsstatus und Status dieses Protokolls. Die Verteilung dieses Memos ist unbegrenzt.
Copyright-Hinweis (Copyright Notice)
Copyright (C) The Internet Society (2003). Alle Rechte vorbehalten.
Inhaltsverzeichnis (Table of Contents)
Hauptabschnitte
- 1. Einleitung
- 2. Notationskonventionen
- 3. UTF-8-Definition
- 4. Syntax von UTF-8-Byte-Sequenzen
- 5. Versionen der Standards
- 6. Byte-Reihenfolgezeichen (BOM)
- 7. Beispiele
- 8. MIME-Registrierung
- 9. IANA-Überlegungen
- 10. Sicherheitsüberlegungen
- 11. Danksagungen
- 12. Änderungen gegenüber RFC 2279
- 13. Normative Referenzen
- 14. Informative Referenzen
Warum UTF-8 wichtig ist
UTF-8 ist die Standard-Zeichenkodierung für das moderne Internet. Fast alle modernen Webanwendungen, APIs und Datenformate verwenden UTF-8.
Hauptvorteile
| Merkmal | Beschreibung | Wichtigkeit |
|---|---|---|
| ASCII-kompatibel | ASCII-Zeichen werden identisch kodiert | ⭐⭐⭐⭐⭐ |
| Keine Byte-Reihenfolge-Probleme | Keine Endianness-Probleme | ⭐⭐⭐⭐⭐ |
| Selbst-synchronisierend | Kann von jeder Position dekodiert werden | ⭐⭐⭐⭐ |
| Platzsparend | 1 Byte für Englisch, 3 Bytes für CJK | ⭐⭐⭐⭐ |
| Globale Unterstützung | Unterstützt alle Unicode-Zeichen | ⭐⭐⭐⭐⭐ |
UTF-8-Kodierungsregeln Schnellreferenz
Kodierungstabelle
Unicode-Bereich Bytes UTF-8-Byte-Muster
─────────────────────────────────────────────
U+0000 - U+007F 1 0xxxxxxx
U+0080 - U+07FF 2 110xxxxx 10xxxxxx
U+0800 - U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
U+10000 - U+10FFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Zeichenbereichsabdeckung
1 Byte (ASCII):
- Lateinische Buchstaben, Zahlen, grundlegende Interpunktion
- Steuerzeichen
- Bereich: U+0000 - U+007F
2 Bytes:
- Erweiterte lateinische Zeichen
- Griechisch, Kyrillisch, Arabisch, Hebräisch
- Bereich: U+0080 - U+07FF
3 Bytes:
- CJK-Zeichen
- Die meisten anderen Schriftsysteme
- Bereich: U+0800 - U+FFFF
4 Bytes:
- Emoji-Symbole
- Historische Schriften, seltene Han-Zeichen
- Bereich: U+10000 - U+10FFFF
Kodierungsbeispiele
ASCII-Zeichen
Zeichen: 'A'
Unicode: U+0041
Binär: 0100 0001
UTF-8: 0x41
Bytes: 1
Kodierungsprozess:
U+0041 < U+007F → 1-Byte-Vorlage verwenden
0xxxxxxx → 01000001 → 0x41
Chinesisches Zeichen
Zeichen: '你'
Unicode: U+4F60
Binär: 0100 1111 0110 0000
UTF-8: 0xE4 0xBD 0xA0
Bytes: 3
Kodierungsprozess:
U+4F60 im Bereich U+0800-U+FFFF → 3-Byte-Vorlage verwenden
1110xxxx 10xxxxxx 10xxxxxx
↓ ↓ ↓
0100 111101 100000
↓ ↓ ↓
11100100 10111101 10100000
0xE4 0xBD 0xA0
Emoji-Zeichen
Zeichen: '😀'
Unicode: U+1F600
Binär: 0001 1111 0110 0000 0000 0000
UTF-8: 0xF0 0x9F 0x98 0x80
Bytes: 4
Kodierungsprozess:
U+1F600 im Bereich U+10000-U+10FFFF → 4-Byte-Vorlage verwenden
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
↓ ↓ ↓ ↓
000011 111101 100000 000000
↓ ↓ ↓ ↓
11110000 10011111 10011000 10000000
0xF0 0x9F 0x98 0x80
Einzigartige Eigenschaften von UTF-8
1. ASCII-Kompatibilität
ASCII-Datei = Gültige UTF-8-Datei
Beispiel:
Hello World (ASCII)
ist auch gültiges UTF-8
Grund:
ASCII verwendet 7 Bits (0xxxxxxx)
UTF-8s 1-Byte-Form ist ASCII
2. Selbst-Synchronisation
UTF-8-Byte-Strom:
... E4 BD A0 E5 A5 BD ...
你 好
Ab jeder Position starten:
- Erstes Byte (1110xxxx oder 110xxxxx oder 11110xxx) kennzeichnet Zeichenbeginn
- Folgebytes (10xxxxxx) werden nie mit einem ersten Byte verwechselt
Beispiel:
E4 BD A0 E5 A5 BD
↑ ↑
Kann als Folgebyte identifiziert werden
Kann ein neues Zeichen von hier identifizieren
3. Keine Byte-Reihenfolge-Probleme
UTF-16 benötigt BOM:
FE FF ... (Big Endian)
FF FE ... (Little Endian)
UTF-8 benötigt kein:
Feste Byte-Reihenfolge, von hoch nach niedrig
Kein BOM erforderlich zur Angabe der Byte-Reihenfolge
Häufige Anwendungen
Webentwicklung
<!-- HTML file -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UTF-8 Example</title>
</head>
<body>
<p>你好,世界! Hello, World! 😀</p>
</body>
</html>
HTTP-Protokoll
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
<!DOCTYPE html>...
JSON-Daten
{
"name": "张三",
"message": "Hello 世界",
"emoji": "😀"
}
Datenbank
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Wichtige Sicherheitsüberlegungen
⚠️ Angriff über überlange Kodierung
Prohibited overlong encodings:
Correct: 'A' → 0x41 (1 byte)
Wrong: 'A' → 0xC0 0x81 (2 bytes, overlong)
'A' → 0xE0 0x80 0x81 (3 bytes, overlong)
Danger:
Overlong encodings may bypass security checks
Example: path traversal "../" in overlong encoding
⚠️ Ungültige Sequenzen
Must reject:
- Isolated continuation bytes (10xxxxxx)
- Beyond Unicode range (>U+10FFFF)
- UTF-16 surrogate pairs (U+D800-U+DFFF)
- Truncated multi-byte sequences
Unterstützung in Programmiersprachen
Python
# Encoding
s = "你好世界"
b = s.encode('utf-8') # bytes object
# Decoding
s = b.decode('utf-8') # str object
# File operations
with open('file.txt', 'r', encoding='utf-8') as f:
content = f.read()
JavaScript
// Encoding
const str = "你好世界";
const encoder = new TextEncoder();
const bytes = encoder.encode(str); // Uint8Array
// Decoding
const decoder = new TextDecoder('utf-8');
const text = decoder.decode(bytes); // string
Java
// Encoding
String str = "你好世界";
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
// Decoding
String decoded = new String(bytes, StandardCharsets.UTF_8);
// File operations
Files.readString(path, StandardCharsets.UTF_8);
Go
// Go's string is natively UTF-8
s := "你好世界"
// Convert to byte slice
b := []byte(s)
// Convert from byte slice
s = string(b)
Leistungsmerkmale
Vergleich der Speichereffizienz
| Textart | UTF-8 | UTF-16 | UTF-32 |
|---|---|---|---|
| Englisch | 1 Byte | 2 Byte | 4 Byte |
| Chinesisch | 3 Byte | 2 Byte | 4 Byte |
| Emoji | 4 Byte | 4 Byte | 4 Byte |
English-dominant text: UTF-8 optimal
CJK-dominant text: UTF-16 slightly better
Mixed text: UTF-8 usually optimal
Verwandte Ressourcen (Related Resources)
- Offizieller Text: RFC 3629 (TXT)
- Offizielle Seite: RFC 3629 DataTracker
- Standard: STD 63
- Ersetzt: RFC 2279
- Unicode-Standard: Unicode.org
- ISO 10646: ISO/IEC 10646
Schnelle Diagnosewerkzeuge
UTF-8-Kodierung erkennen
def is_utf8(data):
"""Detect if data is valid UTF-8"""
try:
data.decode('utf-8')
return True
except UnicodeDecodeError:
return False
Kodierungsprobleme beheben
# Common problem: double encoding
# Original: "你好"
# Wrong display: "ä½ å¥½"
# Fix method:
text = "ä½ å¥½"
fixed = text.encode('latin1').decode('utf-8')
# Result: "你好"
Wichtiger Hinweis: UTF-8 ist der Standardstandard für das moderne Internet. Verwenden Sie immer UTF-8-Kodierung und vermeiden Sie veraltete Kodierungen wie GBK, ISO-8859-1, Windows-1252 usw. Alle neuen Projekte sollten UTF-8 als einzige Zeichenkodierung verwenden.