UTF-8 - UTF-8

UTF-8
Standard Unicode-Standard
Einstufung Unicode Transformation Format , erweitertes ASCII , Codierung mit variabler Breite
Erweitert US-ASCII
Transformiert / Codiert ISO 10646 ( Unicode )
Vorangestellt UTF-1

UTF-8 ist eine Zeichencodierung mit variabler Breite , die für die elektronische Kommunikation verwendet wird. Der vom Unicode-Standard definierte Name leitet sich vom Unicode (oder Universal Coded Character Set ) Transformation Format – 8-Bit ab .

UTF-8 ist in der Lage, alle 1.112.064 gültigen Zeichencodepunkte in Unicode unter Verwendung von ein bis vier Ein- Byte (8-Bit) -Codeeinheiten zu codieren . Codepunkte mit niedrigeren Zahlenwerten, die tendenziell häufiger vorkommen, werden mit weniger Bytes codiert. Es wurde für die Abwärtskompatibilität mit ASCII entwickelt : Die ersten 128 Zeichen von Unicode, die eins zu eins mit ASCII übereinstimmen, werden mit einem einzelnen Byte mit demselben Binärwert wie ASCII codiert, sodass gültiger ASCII-Text gültiges UTF-8 ist -encodierter Unicode auch. Da beim Codieren von Nicht-ASCII-Codepunkten in UTF-8 keine ASCII-Bytes auftreten, kann UTF-8 in den meisten Programmier- und Dokumentsprachen verwendet werden, die bestimmte ASCII-Zeichen auf besondere Weise interpretieren, wie z. B. /( Schrägstrich ) in Dateinamen, \( Backslash ) in Escape-Sequenzen und %in printf .

UTF-8 wurde als überlegene Alternative zu UTF-1 entwickelt , einer vorgeschlagenen Codierung mit variabler Breite und teilweiser ASCII-Kompatibilität, der einige Funktionen wie Selbstsynchronisierung und vollständig ASCII-kompatibler Umgang mit Zeichen wie Schrägstrichen fehlten . Ken Thompson und Rob Pike produzierten im September 1992 die erste Implementierung für das Plan 9- Betriebssystem. Dies führte zur Annahme durch X/Open als Spezifikation für FSS-UTF , die erstmals im Januar 1993 auf USENIX offiziell vorgestellt und anschließend übernommen wurde von der Internet Engineering Task Force (IETF) in RFC 2277 ( BCP 18 ) für zukünftige Internet-Standards arbeiten und Single-Byte-Zeichensätze wie Latin-1 in älteren RFCs ersetzen.

UTF-8 ist mit Abstand die gebräuchlichste Codierung für das World Wide Web und macht ab 2021 über 97 % aller Webseiten und bis zu 100 % für einige Sprachen aus.

Benennung

Der offizielle Code der Internet Assigned Numbers Authority (IANA) für die Codierung lautet "UTF-8". Alle Buchstaben sind Großbuchstaben und der Name wird getrennt. Diese Schreibweise wird in allen Dokumenten des Unicode-Konsortiums verwendet, die sich auf die Kodierung beziehen.

Alternativ kann der Name " utf-8 " von allen Standards verwendet werden, die der IANA-Liste entsprechen (einschließlich CSS- , HTML- , XML- und HTTP-Header ), da bei der Deklaration die Groß-/Kleinschreibung nicht beachtet wird.

Andere Varianten, beispielsweise solche, die den Bindestrich weglassen oder durch ein Leerzeichen ersetzen, zButf8 “ oder „ UTF 8 “, werden von den geltenden Normen nicht als korrekt akzeptiert. Trotzdem können die meisten Webbrowser sie verstehen, und daher erfordern Standards, die bestehende Praktiken beschreiben sollen (wie HTML5), möglicherweise ihre Anerkennung.

Inoffiziell werden UTF-8-BOM und UTF-8-NOBOM manchmal für Textdateien verwendet, die eine Byte-Reihenfolge-Markierung (BOM) enthalten oder nicht . Besonders in Japan wird die UTF-8-Kodierung ohne BOM manchmal als " UTF-8N " bezeichnet.

Windows XP und höher, einschließlich aller unterstützten Windows-Versionen, haben Codepage 65001 , als Synonym für UTF-8 (da Windows 7- Unterstützung für UTF-8 besser ist), und Microsoft hat ein Skript für Windows 10 , um es standardmäßig zu aktivieren sein Programm Microsoft Notepad .

In PCL wird UTF-8 als Symbol-ID "18N" bezeichnet (PCL unterstützt 183 Zeichencodierungen, sogenannte Symbol Sets, die möglicherweise auf eine, 18N, also UTF-8, reduziert werden könnten).

Codierung

Seit der Beschränkung des Unicode-Coderaums auf 21-Bit-Werte im Jahr 2003 ist UTF-8 so definiert, dass er Codepunkte in ein bis vier Bytes codiert, abhängig von der Anzahl der signifikanten Bits im numerischen Wert des Codepunkts. Die folgende Tabelle zeigt den Aufbau der Codierung. Die x- Zeichen werden durch die Bits des Codepunktes ersetzt.

Codepunkt <-> UTF-8-Konvertierung
Erster Codepunkt Letzter Codepunkt Byte 1 Byte 2 Byte 3 Byte 4
U+0000 U+007F 0xxxxxxx
U+0080 U+07FF 110xxxxx 10xxxxxx
U+0800 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+10000 U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Die ersten 128 Zeichen (US-ASCII) benötigen ein Byte. Die nächsten 1.920 Zeichen benötigen zwei Bytes zum Kodieren, was den Rest fast aller lateinischen Alphabete abdeckt , sowie auch IPA-Erweiterungen , griechische , kyrillische , koptische , armenische , hebräische , arabische , syrische , Thaana- und N'Ko- Alphabete als Kombination von diakritischen Zeichen . Drei Byte werden für Zeichen im Rest der Basic Multilingual Plane benötigt , die praktisch alle gebräuchlichen Zeichen enthält, einschließlich der meisten chinesischen, japanischen und koreanischen Zeichen . Vier Bytes werden für Zeichen in den anderen Ebenen von Unicode benötigt , zu denen weniger gebräuchliche CJK-Zeichen , verschiedene historische Schriften, mathematische Symbole und Emoji (piktografische Symbole) gehören.

Ein "Zeichen" kann tatsächlich mehr als 4 Bytes umfassen, zB ein Emoji-Flag-Zeichen benötigt 8 Byte, da es "aus einem Paar von Unicode-Skalarwerten aufgebaut" ist.

Beispiele

Beachten Sie die Kodierung des Eurozeichens , €:

  1. Der Unicode-Codepunkt für "€" ist U+20AC.
  2. Da dieser Codepunkt zwischen U+0800 und U+FFFF liegt, dauert die Codierung drei Bytes.
  3. Hexadezimal 20AC ist binär 0010 0000 10 10 1100 . Die beiden führenden Nullen werden hinzugefügt, da eine Drei-Byte-Codierung genau sechzehn Bits vom Codepunkt benötigt.
  4. Da die Codierung drei Byte lang ist, beginnt das führende Byte mit drei 1er, dann einer 0 ( 1110... )
  5. Die vier höchstwertigen Bits des Codepunkts werden in den verbleibenden vier Bits niedriger Ordnung dieses Bytes ( 1110 0010 ) gespeichert , wobei 12 Bits des Codepunktes noch zu codieren sind ( ... 0000 10 10 1100 ).
  6. Alle Fortsetzungsbytes enthalten genau sechs Bits ab dem Codepunkt. Somit werden die nächsten sechs Bits des Codepunkts in den sechs niederwertigen Bits des nächsten Bytes gespeichert , und 10 wird in den zwei höherwertigen Bits gespeichert, um es als Fortsetzungsbyte zu markieren (also 10 000010 ).
  7. Schließlich werden die letzten sechs Bits des Codepunkts in den sechs niederwertigen Bits des letzten Bytes gespeichert , und wiederum wird 10 in den zwei höherwertigen Bits gespeichert ( 10 101100 ).

Die drei Bytes 1110 0010 10 000010 10 101100 lassen sich prägnanter hexadezimal schreiben , als E2 82 AC .

Die folgende Tabelle fasst diese Konvertierung sowie andere mit unterschiedlichen Längen in UTF-8 zusammen. Die Farben geben an, wie Bits vom Codepunkt auf die UTF-8-Bytes verteilt werden. Zusätzliche Bits, die durch den UTF-8-Codierungsprozess hinzugefügt wurden, werden schwarz dargestellt.

Beispiele für UTF-8-Kodierung
Charakter Binärer Codepunkt Binäres UTF-8 Sechskant UTF-8
$ U+0024 010 0100 0 0100100 24
¢ U+00A2 000 10 10 0010 110 00010 10 100010 C2 A2
U+0939 0000 1001 00 11 1001 1110 0000 10 100100 10 111001 E0 A4 B9
U+20AC 0010 0000 10 10 1100 1110 0010 10 000010 10 101100 E2 82 AC
U+D55C 1101 0101 01 01 1100 1110 1101 10 010101 10 011100 ED 95 9C
𐍈 U+10348 0 00 01 0000 0011 01 00 1000 11110 000 10 010000 10 001101 10 001000 F0 90 8D 88

Oktal

Die Verwendung von sechs Bits pro Byte in UTF-8 zur Darstellung der tatsächlich codierten Zeichen bedeutet, dass die oktale Notation (die 3-Bit-Gruppen verwendet) beim Vergleich von UTF-8-Sequenzen untereinander und bei der manuellen Konvertierung helfen kann.

Oktaler Codepunkt <-> Oktaler UTF-8-Konvertierung
Erster Codepunkt Letzter Codepunkt Codepunkt Byte 1 Byte 2 Byte 3 Byte 4
000 177 xxx xxx
0200 3777 xxyy 3xx 2yy
04000 77777 xyyzz 34x 2yy 2zz
100000 177777 1xyyzz 35x 2yy 2zz
0200000 4177777 xyyzzww 36x 2yy 2zz 2ww

Bei oktaler Notation bleiben die in der Tabelle mit x, y, z oder w gekennzeichneten beliebigen Oktalziffern bei der Konvertierung in oder von UTF-8 unverändert.

Beispiel: Á = U+00C1 = 0301 (in Oktal) wird als 303 201 in UTF-8 (C3 81 in Hex) codiert .
Beispiel: € = U+20AC = 20254 wird als 342 202 254 in UTF-8 kodiert (E2 82 AC in Hex).

Codepage-Layout

Die folgende Tabelle fasst Verwendung der UTF-8 - Codeeinheiten (einzelner Bytes oder octets ) in einem Code - Seite - Format. Die obere Hälfte ( 0_ bis 7_ ) ist für Bytes, die nur in Single-Byte-Codes verwendet werden, sodass sie wie eine normale Codepage aussieht; die untere Hälfte ist für Fortsetzungsbytes ( 8_ bis B_ ) und führende Bytes ( C_ bis F_ ) und wird weiter unten in der Legende erklärt.

UTF-8
_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _EIN _B _C _D _E _F
(1 Byte)
0_
NUL
0000
SOH
0001
STX
0002
ETX
0003
EOT
0004
ENQ
0005
ACK
0006
BEL
0007
BS
0008
HT
0009
LF
000A
VT
000B
FF
000C
CR
000D
SO
000E
SI
000F
(1)
1_
DLE
0010
DC1
0011
DC2
0012
DC3
0013
DC4
0014
NAK
0015
SYN
0016
ETB
0017
CAN
0018
EM
0019
SUB
001A
ESC
001B
FS
001C
GS
001D
RS
001E
US
001F
(1)
2_
SP
0020
!
0021
"
0022
#
0023
0024 $
%
0025
&
0026
'
0027
(
0028
)
0029
*
002A
+
002B
,
002C
-
002D
.
002E
/
002F
(1)
3_
0
0030
1
0031
2
0032
3
0033
4
0034
5
0035
6
0036
7
0037
8
0038
9
0039
:
003A
;
003B
<
003C
=
003D
>
003E
?
003F
(1)
4_
@
0040
A
0041
B
0042
C
0043
D
0044
E
0045
F
0046
G
0047
H
0048
Ich
0049
J
004A
K
004B
L
004C
M
004D
N
004E
O
004F
(1)
5_
P
0050
Q
0051
R
0052
S
0053
T
0054
U
0055
V
0056
W
0057
X
0058
Y
0059
Z
005A
[
005B
\
005C
]
005D
^
005E
_
005F
(1)
6_
`
0060
ein
0061
b
0062
c
0063
d
0064
e
0065
f
0066
g
0067
h
0068
ich
0069
j
006A
k
006B
l
006C
m
006D
n
006E
o
006F
(1)
7_
p
0070
q
0071
r
0072
s
0073
t
0074
u
0075
v
0076
w
0077
x
0078
y
0079
z
007A
{
007B
|
007C
}
007D
~
007E
DEL
007F

8_

+00

+01

+02

+03

+04

+05

+06

+07

+08

+09

+0A

+0B

+0 °C

+0D

+0E

+0F

9_

+10

+11

+12

+13

+14

+15

+16

+17

+18

+19

+1A

+1B

+1 °C

+1 T

+1E

+1F

EIN_

+20

+21

+22

+23

+24

+25

+26

+27

+28

+29

+2A

+2B

+2 °C

+2D

+2E

+2F

B_

+30

+31

+32

+33

+34

+35

+36

+37

+38

+39

+3A

+3B

+3C

+3D

+3E

+3F
(2)
C_
2
0000
2
0040
Latein
0080
Latein
00C0
Latein
0100
Latein
0140
Latein
0180
Latein
01C0
Latein
0200
IPA
0240
IPA
0280
IPA
02C0
Akzente
0300
Akzente
0340
Griechisch
0380
Griechisch
03C0
(2)
D_
Cyrill
0400
Cyrill
0440
Cyrill
0480
Cyrill
04C0
Kyrill
0500
Armeni
0540
Hebräisch
0580
Hebräisch
05C0
Arabisch
0600
Arabisch
0640
Arabisch
0680
Arabisch
06C0
Syrisch
0700
Arabisch
0740
Thaana
0780
NKo
07C0
(3)
E_
Indikator
0800
Sonstiges
1000
Symbol
2000
Kana
3000
CJK
4000
CJK
5000
CJK
6000
CJK
7000
CJK
8000
CJK
9000
Asiatische
A000
Hangul
B000
Hangul
C000
Hangul
D000
PUA
E000
PUA
F000
(4)
F_
SMP…
10000
񀀀
40000
򀀀
80000
SSP…
C0000
SPUA-B
100000
4
140000
4
180000
4
1C0000
5
200000
5
1000000
5
2000000
5
3000000
6
4000000
6
40000000

  Blaue Zellen sind 7-Bit-Sequenzen (Einzelbyte). Es darf kein Fortsetzungsbyte folgen.

  Orangefarbene Zellen mit einem großen Punkt sind ein Fortsetzungsbyte. Die Hexadezimalzahl, die nach dem + -Symbol angezeigt wird, ist der Wert der 6 Bits, die sie hinzufügen. Dieses Zeichen kommt nie als erstes Byte einer Multi-Byte-Sequenz vor.

  Weiße Zellen sind die führenden Bytes für eine Folge von mehreren Bytes, deren Länge am linken Rand der Zeile angezeigt wird. Der Text zeigt die Unicode-Blöcke, die durch Sequenzen codiert sind, die mit diesem Byte beginnen, und der in der Zelle angezeigte hexadezimale Codepunkt ist der niedrigste Zeichenwert, der mit diesem führenden Byte codiert wurde.

  Rote Blutkörperchen dürfen niemals in einer gültigen UTF-8-Sequenz erscheinen. Die ersten beiden roten Zellen ( C0 und C1 ) konnten nur für eine 2-Byte-Kodierung eines 7-Bit-ASCII-Zeichens verwendet werden, das in 1 Byte kodiert werden sollte; wie unten beschrieben, sind solche "überlangen" Sequenzen nicht erlaubt. Um zu verstehen, warum dies so ist, betrachten Sie das Zeichen 128, Hex 80 , Binär 1000 0000 . Zu kodieren als 2 Zeichen, die niedrigen sechs Bits in dem zweiten Zeichen als 128 selbst gespeichert werden , 10 000000 , aber die oberen zwei Bits in dem ersten Zeichen gespeichert als 110 00010 , das Minimum machen erste Zeichen C2. Die roten Zellen in der Zeile F_ ( F5 bis FD ) zeigen führende Bytes von 4-Byte- oder längeren Sequenzen an, die nicht gültig sein können, weil sie Codepunkte codieren würden, die größer als der U+10FFFF-Grenzwert von Unicode (ein Grenzwert, der vom maximalen Codepunkt abgeleitet wird) kodierbar in UTF-16 ). FE und FF stimmen mit keinem zulässigen Zeichenmuster überein und sind daher keine gültigen Startbytes.

  Rosa Zellen sind die führenden Bytes für eine Folge von mehreren Bytes, von denen einige, aber nicht alle möglichen Fortsetzungsfolgen gültig sind. E0 und F0 könnten mit überlangen Kodierungen beginnen, in diesem Fall wird der niedrigste nicht überlang-kodierte Codepunkt angezeigt. F4 kann Codepunkte größer als U+10FFFF starten, die ungültig sind. ED kann die Kodierung eines Codepunktes im Bereich U+D800–U+DFFF starten; diese sind ungültig, da sie für UTF-16- Ersatzhälften reserviert sind .

Überlange Codierungen

Prinzipiell wäre es möglich, die Anzahl der Bytes in einer Codierung aufzublähen, indem man den Codepunkt mit führenden Nullen auffüllt. Um das Eurozeichen € aus dem obigen Beispiel in vier statt in drei Bytes zu kodieren, könnte es mit führenden Nullen aufgefüllt werden , bis es 21 Bit lang ist – 000 000010 000010 101100 , und als 11110 000 10 000010 10 000010 10 101100 (oder F0 82 82 AC hexadezimal). Dies wird als überlange Kodierung bezeichnet .

Der Standard legt fest, dass die korrekte Codierung eines Codepunktes nur die minimale Anzahl von Bytes verwendet, die erforderlich ist, um die signifikanten Bits des Codepunktes zu halten. Längere Codierungen werden als überlang bezeichnet und sind keine gültigen UTF-8-Darstellungen des Codepunkts. Diese Regel hält eine Eins-zu-Eins-Entsprechung zwischen Codepunkten und ihren gültigen Codierungen aufrecht, so dass es für jeden Codepunkt eine eindeutige gültige Codierung gibt. Dadurch wird sichergestellt, dass Zeichenfolgenvergleiche und -suchen gut definiert sind.

Ungültige Sequenzen und Fehlerbehandlung

Nicht alle Bytefolgen sind gültiges UTF-8. Ein UTF-8-Decoder sollte vorbereitet sein für:

  • ungültige Bytes
  • ein unerwartetes Fortsetzungsbyte
  • ein Nichtfortsetzungsbyte vor dem Ende des Zeichens
  • die Zeichenfolge endet vor dem Ende des Zeichens (was beim einfachen Abschneiden von Zeichenfolgen passieren kann)
  • eine überlange Kodierung
  • eine Sequenz, die zu einem ungültigen Codepunkt dekodiert

Viele der ersten UTF-8-Decoder dekodierten diese, ignorierten falsche Bits und akzeptierten überlange Ergebnisse. Sorgfältig erstelltes ungültiges UTF-8 könnte dazu führen, dass sie ASCII-Zeichen wie NUL, Schrägstrich oder Anführungszeichen entweder überspringen oder erstellen. Ungültiges UTF-8 wurde verwendet, um Sicherheitsvalidierungen in hochkarätigen Produkten wie dem IIS- Webserver von Microsoft und dem Servlet-Container Tomcat von Apache zu umgehen . RFC 3629 besagt "Implementierungen des Decodierungsalgorithmus MÜSSEN vor dem Decodieren ungültiger Sequenzen schützen." Der Unicode-Standard verlangt von Decodern, "... jede falsch geformte Codeeinheitssequenz als Fehlerbedingung zu behandeln. Dies garantiert, dass sie weder eine falsch geformte Codeeinheitssequenz interpretiert noch ausgibt."

Seit RFC 3629 (November 2003) sind die von UTF-16 verwendeten oberen und unteren Ersatzhälften (U+D800 bis U+DFFF) und von UTF-16 nicht codierbare Codepunkte (die nach U+10FFFF) keine zulässigen Unicode-Werte. und ihre UTF-8-Codierung muss als ungültige Bytesequenz behandelt werden. Das Nichtdekodieren ungepaarter Ersatzhälften macht es unmöglich, ungültiges UTF-16 (wie Windows-Dateinamen oder UTF-16, das zwischen den Ersatzwerten aufgeteilt wurde) als UTF-8 zu speichern, während dies mit WTF-8 möglich ist .

Einige Implementierungen von Decodern lösen bei Fehlern Ausnahmen aus. Dies hat den Nachteil, dass ansonsten harmlose Fehler (z. B. ein "keine solche Datei"-Fehler) in einen Denial-of-Service umgewandelt werden können . Beispielsweise würden frühe Versionen von Python 3.0 sofort beendet werden, wenn die Befehlszeile oder die Umgebungsvariablen ungültiges UTF-8 enthielten. Eine alternative Vorgehensweise besteht darin, Fehler durch ein Ersatzzeichen zu ersetzen. Seit Unicode 6 (Oktober 2010) empfiehlt der Standard (Kapitel 3) eine „Best Practice“, bei der der Fehler endet, sobald ein unzulässiges Byte auftritt. In diesen Decodern sind E1,A0,C0 zwei Fehler (2 Bytes im ersten). Dies bedeutet, dass ein Fehler nicht länger als drei Byte ist und niemals den Anfang eines gültigen Zeichens enthält, und es gibt 21.952 verschiedene mögliche Fehler. Die Norm empfiehlt außerdem, jeden Fehler durch das Ersetzungszeichen „ “ (U+FFFD) zu ersetzen .

Byte-Reihenfolge-Marke

Wenn das UTF-16-Unicode- Bytereihenfolgezeichen (BOM, U+FEFF) am Anfang einer UTF-8-Datei steht, sind die ersten drei Bytes 0xEF , 0xBB , 0xBF .

Der Unicode-Standard fordert oder empfiehlt weder die Verwendung der BOM für UTF-8, warnt jedoch davor, dass sie am Anfang einer Datei angetroffen werden kann, die von einer anderen Codierung transcodiert wurde. Während mit UTF-8 codierter ASCII-Text mit ASCII abwärtskompatibel ist, trifft dies nicht zu, wenn die Empfehlungen des Unicode-Standards ignoriert und eine Stückliste hinzugefügt wird. Eine Stückliste kann Software verwirren, die nicht darauf vorbereitet ist, aber ansonsten UTF-8 akzeptieren kann, zB Programmiersprachen, die Nicht-ASCII-Bytes in String-Literalen zulassen, aber nicht am Anfang der Datei. Dennoch gab und gibt es Software, die beim Schreiben von UTF-8 immer eine Stückliste einfügt und sich weigert, UTF-8 richtig zu interpretieren, es sei denn, das erste Zeichen ist eine Stückliste (oder die Datei enthält nur ASCII).

Einige Programmiersprachen und Dateiformate haben ihre eigene Art, die Verwendung von Codierungen wie UTF-8 im Quellcode zu kennzeichnen. Beispiele sind HTML <meta charset="UTF-8"/> und Python 2.7 # coding: utf-8

Annahme

Nutzung der wichtigsten Codierungen im Web von 2001 bis 2012, wie von Google aufgezeichnet, wobei UTF-8 2008 alle anderen überholte und 2012 über 60% des Webs (seitdem fast 100%) erreicht hat. Die ASCII- only-Zahl umfasst alle Webseiten, die nur ASCII-Zeichen enthalten, unabhängig vom deklarierten Header.

UTF-8 ist die Empfehlung der WHATWG für HTML- und DOM- Spezifikationen, und das Internet Mail Consortium empfiehlt, dass alle E-Mail-Programme E-Mail mit UTF-8 anzeigen und erstellen können. Das World Wide Web Consortium empfiehlt UTF-8 als Standardcodierung in XML und HTML (und nicht nur UTF-8 zu verwenden, sondern auch in Metadaten anzugeben ), „auch wenn alle Zeichen im ASCII- Bereich liegen. 8-Kodierungen können zu unerwarteten Ergebnissen führen". Viele andere Standards unterstützen nur UTF-8, z. B. erfordert der offene JSON- Austausch dies.

UTF-8 ist seit 2008 die gängigste Kodierung für das World Wide Web . Stand Oktober 2021 macht UTF-8 durchschnittlich 97,3% aller Webseiten aus; und 988 der 1.000 bestplatzierten Webseiten. UTF-8 enthält ASCII als Teilmenge; fast keine Websites deklarieren nur ASCII verwendet. Mehrere Sprachen verwenden 100,0 % UTF-8.

Für lokale Textdateien ist die UTF-8-Nutzung geringer, und viele ältere Einzelbyte- (und CJK -Multibyte-) Codierungen werden weiterhin verwendet. Die Hauptursache sind Editoren, die UTF-8 nicht anzeigen oder schreiben, es sei denn, das erste Zeichen in einer Datei ist eine Bytereihenfolgemarkierung (BOM), wodurch es für andere Software unmöglich wird, UTF-8 zu verwenden, ohne umgeschrieben zu werden, um die Bytereihenfolgemarkierung zu ignorieren bei der Eingabe und fügen Sie sie bei der Ausgabe hinzu. In letzter Zeit gab es einige Verbesserungen, Notepad unter Windows 10 schreibt standardmäßig UTF-8 ohne BOM, und einige Systemdateien unter Windows 11 erfordern UTF-8, und fast alle Dateien auf macOS und Linux müssen UTF-8 sein (ohne eine Stückliste). Java , mit seiner NIO- API, liest und schreibt standardmäßig UTF-8-Dateien und wird dies auch für alle anderen Datei-APIs tun. Dies gilt bereits für alle APIs auf den meisten Plattformen, mit Ausnahme von Windows . "Die Wahl von UTF-8 gilt nur für Standard-Java-APIs und nicht für die Sprache Java, die weiterhin UTF-16 verwenden wird." Viele andere Programmiersprachen verwenden standardmäßig UTF-8 für I/O; oder planen, zu UTF-8 zu migrieren, wie Python, das sich darauf vorbereitet, "die Standardcodierung auf UTF-8 zu ändern [da es] zur De-facto-Standardtextcodierung geworden ist". Die meisten Datenbanken unterstützen UTF-8 (manchmal die einzige Option wie bei einigen Dateiformaten), einschließlich der von Microsoft seit SQL Server 2019, was zu einer Geschwindigkeitssteigerung von 35 % und einer "fast 50 %igen Reduzierung des Speicherbedarfs" führt.

Intern ist die Softwarenutzung geringer, wobei UTF-16 oder UCS-2 insbesondere unter Windows, aber auch von JavaScript , Python , Qt und vielen anderen plattformübergreifenden Softwarebibliotheken im Einsatz sind. Die Kompatibilität mit der Windows-API ist der Hauptgrund dafür, obwohl auch die Überzeugung, dass die direkte Indizierung von BMP die Geschwindigkeit verbessert, ein Faktor war. Neuere Software verwendet UTF-8: Das Standard-String-Primitive, das in Go , Julia , Rust , Swift 5 und PyPy verwendet wird, ist UTF-8, eine zukünftige Version von Python beabsichtigt, Strings als UTF-8 zu speichern, und moderne Versionen von Microsoft Visual Studio verwenden intern UTF-8 (erfordern jedoch immer noch einen Befehlszeilenschalter, um UTF-8 zu lesen oder zu schreiben). UTF-8 ist ab C++20 die "einzige Textkodierung, die vom C++-Standard unterstützt werden muss" . Ab Mai 2019 hat Microsoft seinen Kurs umgekehrt, nur UTF-16 für die Windows-API zu unterstützen, und bietet die Möglichkeit, UTF-8 als "Codepage" für die Multi-Byte-API festzulegen (vorher war dies unmöglich), und jetzt Microsoft empfiehlt (Programmierern) die Verwendung von UTF-8 für Apps der Universal Windows Platform (UWP), während weiterhin eine ältere "Unicode"-Schnittstelle (d. h. UTF-16) beibehalten wird.

Geschichte

Die International Organization for Standardization (ISO) machte sich 1989 daran, einen universellen Multi-Byte-Zeichensatz zusammenzustellen. Der Entwurf des ISO 10646-Standards enthielt einen nicht erforderlichen Anhang namens UTF-1, der eine Bytestrom-Codierung seiner 32-Bit- Codepunkte bereitstellte . Diese Kodierung war unter anderem aus Performancegründen nicht zufriedenstellend, und das größte Problem war wahrscheinlich, dass es keine klare Trennung zwischen ASCII und Nicht-ASCII gab: Neue UTF-1-Tools wären mit ASCII-kodiertem Text abwärtskompatibel, aber UTF-1-codierter Text könnte vorhandenen Code erwartet ASCII (oder verwirren erweitern ASCII ), weil es Fortsetzung Bytes im Bereich 0x21-0x7E das bedeutet etwas anderes in ASCII, zB 0x2F für ‚/‘, die enthalten könnte Unix Pfad Verzeichnisseparator , und dieses Beispiel spiegelt sich im Namen und einleitenden Text seiner Ersetzung wider. Die folgende Tabelle wurde aus einer Textbeschreibung im Anhang abgeleitet.

UTF-1
Anzahl
Bytes
Erster
Codepunkt
Letzter
Codepunkt
Byte 1 Byte 2 Byte 3 Byte 4 Byte 5
1 U+0000 U+009F 00–9F
2 U+00A0 U+00FF A0 A0–FF
2 U+0100 U+4015 A1–F5 21–7E, A0–FF
3 U+4016 U+38E2D F6–FB 21–7E, A0–FF 21–7E, A0–FF
5 U+38E2E U+7FFFFFFFF FC–FF 21–7E, A0–FF 21–7E, A0–FF 21–7E, A0–FF 21–7E, A0–FF

Im Juli 1992 suchte das X/Open- Komitee XoJIG nach einer besseren Kodierung. Dave Prosser von Unix System Laboratories legte einen Vorschlag für einen Vorschlag vor, der schnellere Implementierungsmerkmale aufwies und die Verbesserung einführte, dass 7-Bit-ASCII-Zeichen nur sich selbst darstellen würden; alle Multibyte-Sequenzen würden nur Bytes enthalten, bei denen das High-Bit gesetzt war. Der Name File System Safe UCS Transformation Format (FSS-UTF) und der Großteil des Textes dieses Vorschlags wurden später in der endgültigen Spezifikation beibehalten.

FSS-UTF

FSS-UTF-Vorschlag (1992)
Anzahl
Bytes
Erster
Codepunkt
Letzter
Codepunkt
Byte 1 Byte 2 Byte 3 Byte 4 Byte 5
1 U+0000 U+007F 0xxxxxxx
2 U+0080 U+207F 10xxxxxx 1xxxxxxx
3 U+2080 U+8207F 110xxxxx 1xxxxxxx 1xxxxxxx
4 U+82080 U+208207F 1110xxxx 1xxxxxxx 1xxxxxxx 1xxxxxxx
5 U+2082080 U+7FFFFFFFF 11110xxx 1xxxxxxx 1xxxxxxx 1xxxxxxx 1xxxxxxx

Im August 1992 wurde dieser Vorschlag von einem IBM X/Open-Vertreter an interessierte Parteien verteilt. Eine Modifikation von Ken Thompson von der Plan 9- Betriebssystemgruppe bei Bell Labs machte es etwas weniger biteffizient als der vorherige Vorschlag, ermöglichte es jedoch entscheidend selbstsynchronisierend , sodass ein Reader überall starten und Bytesequenzgrenzen sofort erkennen konnte. Außerdem wurde die Verwendung von Verzerrungen aufgegeben und stattdessen die Regel hinzugefügt, dass nur die kürzestmögliche Codierung zulässig ist; der zusätzliche Verlust an Kompaktheit ist relativ unbedeutend, aber Leser müssen jetzt auf ungültige Codierungen achten, um Zuverlässigkeits- und insbesondere Sicherheitsprobleme zu vermeiden. Thompsons Entwurf wurde am 2. September 1992 auf einem Tischset in einem Diner in New Jersey mit Rob Pike entworfen . In den folgenden Tagen implementierten Pike und Thompson es und aktualisierten Plan 9 , um es durchgehend zu verwenden, und teilten ihren Erfolg dann X/Open mit, das es als Spezifikation für FSS-UTF akzeptierte.

FSS-UTF (1992) / UTF-8 (1993)
Anzahl
Bytes
Erster
Codepunkt
Letzter
Codepunkt
Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
1 U+0000 U+007F 0xxxxxxx
2 U+0080 U+07FF 110xxxxx 10xxxxxx
3 U+0800 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
4 U+10000 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5 U+20000 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6 U+4000000 U+7FFFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8 wurde erstmals offiziell auf der USENIX- Konferenz in San Diego vom 25. bis 29. Januar 1993 vorgestellt. Die Internet Engineering Task Force hat UTF-8 in ihre Policy on Character Sets and Languages ​​in RFC 2277 ( BCP 18) für das zukünftige Internet übernommen Standards funktionieren und ersetzen Single-Byte-Zeichensätze wie Latin-1 in älteren RFCs.

Im November 2003 wurde UTF-8 durch RFC  3629 eingeschränkt , um die Einschränkungen der UTF-16- Zeichencodierung zu erfüllen : Durch das explizite Verbot von Codepunkten, die den hohen und niedrigen Ersatzzeichen entsprechen, wurden mehr als 3% der Drei-Byte-Sequenzen entfernt, und die Endung bei U+10FFFF mehr als 48% der 4-Byte-Sequenzen und alle 5- und 6-Byte-Sequenzen entfernt.

Normen

Es gibt mehrere aktuelle Definitionen von UTF-8 in verschiedenen Standarddokumenten:

  • RFC  3629 / STD 63 (2003), der UTF-8 als Standard-Internetprotokollelement festlegt
  • RFC  5198 definiert UTF-8 NFC für Network Interchange (2008)
  • ISO/IEC 10646: 2014 §9.1 (2014)
  • Der Unicode-Standard, Version 11.0 (2018)

Sie ersetzen die Definitionen in den folgenden veralteten Werken:

  • Der Unicode-Standard, Version 2.0 , Anhang A (1996)
  • ISO/IEC 10646-1: 1993 Änderung 2 / Anhang R (1996)
  • RFC  2044 (1996)
  • RFC  2279 (1998)
  • Der Unicode-Standard, Version 3.0 , §2.3 (2000) plus Berichtigung Nr. 1: UTF-8 Shortest Form (2000)
  • Unicode-Standard-Anhang #27: Unicode 3.1 (2001)
  • Der Unicode-Standard, Version 5.0 (2006)
  • Der Unicode-Standard, Version 6.0 (2010)

Sie sind in ihrer allgemeinen Mechanik alle gleich, wobei die Hauptunterschiede in Fragen wie dem zulässigen Bereich von Codepunktwerten und der sicheren Handhabung ungültiger Eingaben liegen.

Vergleich mit anderen Kodierungen

Einige der wichtigen Merkmale dieser Codierung sind wie folgt:

  • Abwärtskompatibilität: Die Abwärtskompatibilität mit ASCII und die enorme Menge an Software, die zur Verarbeitung von ASCII-codiertem Text entwickelt wurde, waren die Hauptantriebskräfte hinter der Entwicklung von UTF-8. In UTF-8 werden einzelne Bytes mit Werten im Bereich von 0 bis 127 direkt Unicode-Codepunkten im ASCII-Bereich zugeordnet. Einzelne Bytes in diesem Bereich stellen Zeichen dar, wie sie es in ASCII tun. Darüber hinaus erscheinen 7-Bit-Bytes (Bytes, bei denen das höchstwertige Bit 0) ist, niemals in einer Multi-Byte-Sequenz, und keine gültige Multi-Byte-Sequenz wird zu einem ASCII-Codepunkt decodiert. Eine Folge von 7-Bit-Bytes ist sowohl gültiges ASCII als auch gültiges UTF-8 und stellt bei beiden Interpretationen dieselbe Zeichenfolge dar. Daher repräsentieren die 7-Bit-Bytes in einem UTF-8-Stream alle und nur die ASCII-Zeichen im Stream. Daher funktionieren viele Textprozessoren, Parser, Protokolle, Dateiformate, Textanzeigeprogramme usw., die ASCII-Zeichen für Formatierungs- und Steuerzwecke verwenden, weiterhin wie beabsichtigt, indem sie den UTF-8-Bytestrom als eine Folge von Einzel- Byte-Zeichen, ohne die Multi-Byte-Sequenzen zu decodieren. ASCII-Zeichen, auf die sich die Verarbeitung bezieht, wie beispielsweise Satzzeichen, Leerzeichen und Steuerzeichen, werden niemals als Multi-Byte-Sequenzen codiert. Es ist daher für solche Prozessoren sicher, die Multibyte-Sequenzen einfach zu ignorieren oder durchzugehen, ohne sie zu decodieren. ASCII-Leerzeichen können beispielsweise verwendet werden, um einen UTF-8-Stream in Wörter zu tokenisieren ; ASCII-Zeilenvorschübe können verwendet werden, um einen UTF-8-Stream in Zeilen aufzuteilen; und ASCII-NUL-Zeichen können verwendet werden, um UTF-8-codierte Daten in nullterminierte Zeichenfolgen aufzuteilen. In ähnlicher Weise werden viele Formatzeichenfolgen, die von Bibliotheksfunktionen wie "printf" verwendet werden, UTF-8-codierte Eingabeargumente korrekt verarbeiten.
  • Fallback und automatische Erkennung: Nur eine kleine Teilmenge möglicher Byte-Strings ist ein gültiger UTF-8-String: die Bytes C0, C1 und F5 bis FF können nicht erscheinen, und Bytes mit dem hohen Bitsatz müssen paarweise sein, und andere Anforderungen . Es ist äußerst unwahrscheinlich, dass ein lesbarer Text in einem erweiterten ASCII gültiges UTF-8 ist. Ein Teil der Popularität von UTF-8 ist darauf zurückzuführen, dass es auch für diese eine Form der Abwärtskompatibilität bietet. Ein UTF-8-Prozessor, der fälschlicherweise erweitertes ASCII als Eingabe empfängt, kann dies also mit sehr hoher Zuverlässigkeit "auto-detektieren". Fallback-Fehler sind False-Negatives, und diese werden selten sein. Darüber hinaus sind in vielen Anwendungen, wie beispielsweise der Textanzeige, die Folgen eines falschen Fallbacks in der Regel gering. Ein UTF-8-Stream kann einfach Fehler enthalten, was dazu führt, dass das automatische Erkennungsschema falsch positive Ergebnisse erzeugt; Die automatische Erkennung ist jedoch in den meisten Fällen, insbesondere bei längeren Texten, erfolgreich und wird häufig verwendet. Es funktioniert auch, um 8-Bit-Bytes "zurückzufallen" oder zu ersetzen, indem der entsprechende Codepunkt für eine Legacy-Codierung verwendet wird, nur wenn Fehler in UTF-8 erkannt werden, was eine Wiederherstellung ermöglicht, selbst wenn UTF-8 und Legacy-Codierung in derselben verkettet sind Datei.
  • Präfixcode : Das erste Byte gibt die Anzahl der Bytes in der Sequenz an. Das Lesen aus einem Stream kann jede einzelne vollständig empfangene Sequenz sofort decodieren, ohne zuerst auf das erste Byte einer nächsten Sequenz oder eine End-of-Stream-Anzeige warten zu müssen. Die Länge von Multi-Byte-Sequenzen kann vom Menschen leicht bestimmt werden, da es sich einfach um die Anzahl der höherwertigen Einsen im führenden Byte handelt. Ein falsches Zeichen wird nicht decodiert, wenn ein Stream mitten in der Sequenz endet.
  • Selbstsynchronisation : Die führenden Bytes und die Fortsetzungsbytes haben keine gemeinsamen Werte (Fortsetzungsbytes beginnen mit den Bits 10, während einzelne Bytes mit 0 beginnen und längere führende Bytes mit 11 beginnen ). Dies bedeutet, dass eine Suche nicht versehentlich die Sequenz für ein Zeichen findet, die in der Mitte eines anderen Zeichens beginnt. Es bedeutet auch, dass der Anfang eines Zeichens an einer zufälligen Position gefunden werden kann, indem maximal 3 Byte gesichert werden, um das führende Byte zu finden. Ein falsches Zeichen wird nicht decodiert, wenn ein Stream mitten in der Sequenz beginnt, und eine kürzere Sequenz wird niemals in einer längeren vorkommen.
  • Sortierreihenfolge: Durch die gewählten Werte der führenden Bytes kann eine Liste von UTF-8-Strings in Code-Point-Reihenfolge sortiert werden, indem die entsprechenden Byte-Sequenzen sortiert werden.

Einzelbyte

  • UTF-8 kann jedes Unicode-Zeichen codieren , wodurch die Notwendigkeit vermieden wird, eine " Codepage " herauszufinden und festzulegen oder anderweitig anzugeben, welcher Zeichensatz verwendet wird, und ermöglicht die gleichzeitige Ausgabe in mehreren Skripten. Für viele Skripte wurde mehr als eine Single-Byte-Codierung verwendet, sodass selbst das Wissen, dass das Skript nicht genügend Informationen enthält, um es korrekt anzuzeigen.
  • Die Bytes 0xFE und 0xFF erscheinen nicht, sodass ein gültiger UTF-8-Stream nie mit der UTF-16- Bytereihenfolgemarkierung übereinstimmt und daher nicht damit verwechselt werden kann. Das Fehlen von 0xFF (0377) macht es auch überflüssig, dieses Byte in Telnet (und FTP-Steuerungsverbindung) zu umgehen .
  • UTF-8-codierter Text ist größer als spezialisierte Einzelbyte-Codierungen, mit Ausnahme von einfachen ASCII-Zeichen. Bei Skripten, die 8-Bit-Zeichensätze mit nicht-lateinischen Zeichen in der oberen Hälfte verwenden (wie die meisten Codepages des kyrillischen und griechischen Alphabets ), sind die Zeichen in UTF-8 doppelt so groß. Bei einigen Schriften wie Thai und Devanagari (die von verschiedenen südasiatischen Sprachen verwendet werden) verdreifachen sich die Zeichen. Es gibt sogar Beispiele, bei denen ein einzelnes Byte in Unicode zu einem zusammengesetzten Zeichen wird und damit in UTF-8 sechsmal größer ist. Dies hat in Indien und anderen Ländern zu Einwänden geführt.
  • In UTF-8 (oder jeder anderen Codierung mit variabler Länge) ist es möglich, eine Zeichenfolge in der Mitte eines Zeichens zu teilen oder abzuschneiden . Wenn die beiden Teile später nicht wieder angehängt werden, bevor sie als Zeichen interpretiert werden, kann dies sowohl am Ende des vorherigen Abschnitts als auch am Anfang des nächsten eine ungültige Sequenz einführen, und einige Decoder behalten diese Bytes nicht bei und führen zu Datenverlust. Da UTF-8 selbstsynchronisiert ist, führt dies jedoch nie ein anderes gültiges Zeichen ein, und es ist auch ziemlich einfach, den Abschneidepunkt rückwärts an den Anfang eines Zeichens zu verschieben.
  • Wenn die Codepunkte alle gleich groß sind, ist die Messung einer festen Anzahl von ihnen einfach. Aufgrund der Dokumentation aus der ASCII-Ära, in der "Zeichen" als Synonym für "Byte" verwendet wird, wird dies oft als wichtig angesehen. Durch das Messen von Stringpositionen mit Bytes anstelle von "Zeichen" können die meisten Algorithmen jedoch einfach und effizient für UTF-8 angepasst werden. Die Suche nach einem String innerhalb eines langen Strings kann zB byteweise erfolgen; die Selbstsynchronisierungseigenschaft verhindert Fehlalarme.

Andere Multibyte

  • UTF-8 kann jedes Unicode- Zeichen codieren . Dateien in verschiedenen Skripten können korrekt angezeigt werden, ohne dass die richtige Codepage oder Schriftart ausgewählt werden muss. Chinesisch und Arabisch können beispielsweise ohne spezielles Markup oder manuelle Einstellungen, die eine Kodierung festlegen, in dieselbe Datei geschrieben werden.
  • UTF-8 ist selbstsynchronisierend : Zeichengrenzen werden durch Scannen nach wohldefinierten Bitmustern in beide Richtungen leicht identifiziert. Wenn Bytes aufgrund eines Fehlers oder einer Beschädigung verloren gehen , kann man immer das nächste gültige Zeichen finden und die Verarbeitung fortsetzen. Wenn eine Zeichenfolge gekürzt werden muss, damit sie in ein bestimmtes Feld passt, kann das vorherige gültige Zeichen leicht gefunden werden. Viele Multibyte-Kodierungen wie Shift JIS sind viel schwieriger zu resynchronisieren. Dies bedeutet auch, dass mit UTF-8 byteorientierte String-Suchalgorithmen verwendet werden können (da ein Zeichen gleich einem aus so vielen Bytes zusammengesetzten "Wort" ist), können optimierte Versionen der Byte-Suche hardwarebedingt viel schneller sein Support- und Lookup-Tabellen mit nur 256 Einträgen. Die Selbstsynchronisation erfordert jedoch, dass für diese Merker in jedem Byte Bits reserviert werden, wodurch die Größe erhöht wird.
  • Effiziente Kodierung mit einfachen bitweisen Operationen . UTF-8 erfordert keine langsameren mathematischen Operationen wie Multiplikation oder Division (im Gegensatz zu Shift JIS , GB 2312 und anderen Codierungen).
  • UTF-8 benötigt mehr Platz als eine Multi-Byte-Codierung, die für ein bestimmtes Skript entwickelt wurde. Ostasiatische Legacy-Codierungen verwendeten im Allgemeinen zwei Bytes pro Zeichen, benötigen jedoch in UTF-8 drei Bytes pro Zeichen.

UTF-16

  • Byte-Codierungen und UTF-8 werden in Programmen durch Byte-Arrays dargestellt, und oft muss beim Konvertieren von Quellcode von einer Byte-Codierung in UTF-8 nichts an einer Funktion vorgenommen werden. UTF-16 mit 16-Bit - Wort - Arrays dargestellt wird, und die Umstellung auf UTF-16 gleichzeitig die Kompatibilität mit vorhandenen ASCII - basierten Programmen (wie mit Windows - done) erfordert jede API und Datenstruktur , die einen String dupliziert wird, ein Version, die Byte-Strings akzeptiert, und eine andere Version, die UTF-16 akzeptiert. Wenn keine Abwärtskompatibilität erforderlich ist, muss die gesamte Zeichenfolgenbehandlung noch geändert werden.
  • In UTF-8 kodierter Text ist kleiner als der gleiche in UTF-16 kodierte Text, wenn mehr Codepunkte unter U+0080 als im Bereich U+0800..U+FFFF liegen. Dies gilt für alle modernen europäischen Sprachen. Dies gilt aufgrund der großen Anzahl von Leerzeichen, Zeilenumbrüchen, Ziffern und HTML-Markup in typischen Dateien oft sogar für Sprachen wie Chinesisch.
  • Die meiste Kommunikation (zB HTML und IP) und Speicherung (zB für Unix) wurde für einen Strom von Bytes entworfen . Ein UTF-16-String muss für jede Codeeinheit ein Bytepaar verwenden:
    • Die Reihenfolge dieser beiden Bytes wird zum Problem und muss im UTF-16-Protokoll angegeben werden, beispielsweise mit einer Bytereihenfolgemarkierung .
    • Wenn in UTF-16 eine ungerade Anzahl von Bytes fehlt, ist der gesamte Rest der Zeichenfolge bedeutungsloser Text. Alle in UTF-8 fehlenden Bytes ermöglichen eine genaue Wiederherstellung des Textes, beginnend mit dem nächsten Zeichen nach den fehlenden Bytes.

Derivate

Die folgenden Implementierungen weisen geringfügige Unterschiede zur UTF-8-Spezifikation auf. Sie sind mit der UTF-8-Spezifikation nicht kompatibel und können von konformen UTF-8-Anwendungen abgelehnt werden.

CESU-8

Unicode Technical Report #26 weist den Namen CESU-8 einer nicht standardmäßigen Variante von UTF-8 zu, bei der Unicode-Zeichen in zusätzlichen Ebenen mit sechs Bytes codiert werden, anstatt mit den von UTF-8 benötigten vier Bytes. Die CESU-8-Codierung behandelt jede Hälfte eines Vier-Byte-UTF-16-Ersatzpaares als Zwei-Byte-UCS-2-Zeichen, was zwei Drei-Byte-UTF-8-Zeichen ergibt, die zusammen das ursprüngliche Zusatzzeichen darstellen. Unicode-Zeichen innerhalb der Basic Multilingual Plane erscheinen wie normalerweise in UTF-8. Der Bericht wurde verfasst, um die Existenz von Daten, die als CESU-8 kodiert sind, anzuerkennen und zu formalisieren, obwohl das Unicode-Konsortium davon abrät, und stellt fest, dass ein möglicher absichtlicher Grund für die CESU-8-Kodierung die Beibehaltung der UTF-16-Binärkollation ist.

Die CESU-8-Codierung kann aus der Konvertierung von UTF-16-Daten mit zusätzlichen Zeichen in UTF-8 resultieren, wobei Konvertierungsmethoden verwendet werden, die UCS-2-Daten annehmen, was bedeutet, dass sie keine UTF-16-Zusatzzeichen mit vier Bytes kennen. Dies ist in erster Linie ein Problem bei Betriebssystemen, die intern ausgiebig UTF-16 verwenden, wie z. B. Microsoft Windows .

In Oracle Database verwendet der UTF8Zeichensatz die CESU-8-Codierung und ist veraltet. Der AL32UTF8Zeichensatz verwendet standardkonforme UTF-8-Codierung und wird bevorzugt.

CESU-8 darf nicht in HTML5- Dokumenten verwendet werden.

MySQL utf8mb3

In MySQL ist der utf8mb3Zeichensatz als UTF-8-codierte Daten mit maximal drei Bytes pro Zeichen definiert, was bedeutet, dass nur Unicode-Zeichen in der Basic Multilingual Plane (dh von UCS-2 ) unterstützt werden. Unicode-Zeichen in ergänzenden Ebenen werden ausdrücklich nicht unterstützt. utf8mb3ist zugunsten des utf8mb4Zeichensatzes veraltet , der die standardkonforme UTF-8-Codierung verwendet. utf8ist ein Alias ​​für utf8mb3, soll aber utf8mb4in einer zukünftigen Version von MySQL ein Alias ​​für werden . Es ist möglich, jedoch nicht unterstützt, CESU-8-codierte Daten in zu speichern utf8mb3, indem UTF-16-Daten mit zusätzlichen Zeichen behandelt werden, als ob es sich um UCS-2 handelt.

Modifiziertes UTF-8

Modifiziertes UTF-8 (MUTF-8) stammt aus der Programmiersprache Java . In Modified UTF-8 verwendet das Nullzeichen (U+0000) die überlange Zwei-Byte-Codierung 110 00000 10 000000 (hexadezimal C0 80 ) anstelle von 00000000 (hexadezimal 00 ). Modifizierte UTF-8-Strings enthalten niemals tatsächliche Nullbytes, können jedoch alle Unicode-Codepunkte einschließlich U+0000 enthalten, wodurch solche Strings (mit einem angehängten Nullbyte) von herkömmlichen nullterminierten Stringfunktionen verarbeitet werden können. Alle bekannten modifizierten UTF-8-Implementierungen behandeln auch die Ersatzpaare wie in CESU-8 .

Im normalen Gebrauch unterstützt die Sprache Standard-UTF-8 beim Lesen und Schreiben von Strings durch InputStreamReaderund OutputStreamWriter(wenn es der Standardzeichensatz der Plattform ist oder vom Programm angefordert wird). Aber es nutzt Modified UTF-8 für Objekt - Serialisierung unter anderen Anwendungen von DataInputund DataOutputfür das Java Native Interface und für konstante Strings in dem Einbetten von Klassendateien .

Das von Dalvik definierte dex-Format verwendet ebenfalls dasselbe modifizierte UTF-8, um Zeichenfolgenwerte darzustellen. Tcl verwendet auch dasselbe modifizierte UTF-8 wie Java für die interne Darstellung von Unicode-Daten, verwendet jedoch striktes CESU-8 für externe Daten.

WTF-8

In WTF-8 (Wobbly Transformation Format, 8-Bit) sind ungepaarte Ersatzhälften (U+D800 bis U+DFFF) erlaubt. Dies ist notwendig, um möglicherweise ungültiges UTF-16 zu speichern, wie z. B. Windows-Dateinamen. Viele Systeme, die mit UTF-8 umgehen, arbeiten auf diese Weise, ohne eine andere Kodierung zu berücksichtigen, da es einfacher ist.

(Der Begriff "WTF-8" wurde auch humorvoll verwendet, um sich auf fälschlicherweise doppelt codiertes UTF-8 zu beziehen, manchmal mit der Implikation, dass CP1252 Bytes die einzigen codierten sind.)

PEP 383

Version 3 der Programmiersprache Python behandelt jedes Byte eines ungültigen UTF-8-Bytestreams als Fehler (siehe auch Änderungen mit dem neuen UTF-8-Modus in Python 3.7); dies ergibt 128 verschiedene mögliche Fehler. Es wurden Erweiterungen erstellt, um jede Bytesequenz, von der angenommen wird, dass sie UTF-8 ist, verlustfrei in UTF-16 oder UTF-32 umgewandelt werden, indem die 128 möglichen Fehlerbytes in reservierte Codepunkte übersetzt und diese Codepunkte wieder in Fehler umgewandelt werden Byte zur Ausgabe von UTF-8. Der gebräuchlichste Ansatz besteht darin, die Codes in U+DC80...U+DCFF zu übersetzen, die niedrige (nachgestellte) Ersatzwerte sind und somit "ungültiges" UTF-16, wie es von Pythons PEP 383 (oder "surrogateescape") verwendet wird. sich nähern. Eine andere Kodierung namens MirBSD OPTU-8/16 wandelt sie in U+EF80...U+EFFF in einem Private Use Area um . Bei beiden Ansätzen wird der Bytewert in den unteren acht Bits des Ausgangscodepunkts codiert.

Diese Codierungen sind sehr nützlich, weil sie, wenn überhaupt, erst viel später mit "ungültigen" Byte-Strings umgehen müssen und zulassen, dass "Text"- und "Daten"-Byte-Arrays dasselbe Objekt sind. Wenn ein Programm intern UTF-16 verwenden möchte, sind diese erforderlich, um Dateinamen zu erhalten und zu verwenden, die ungültiges UTF-8 verwenden können; Da die Windows-Dateisystem-API UTF-16 verwendet, besteht weniger Notwendigkeit, ungültiges UTF-8 zu unterstützen.

Damit die Codierung reversibel ist, müssen die Standard-UTF-8-Codierungen der für fehlerhafte Bytes verwendeten Codepunkte als ungültig betrachtet werden. Dadurch ist die Kodierung inkompatibel mit WTF-8 oder CESU-8 (allerdings nur für 128 Codepunkte). Bei der Neucodierung ist auf Sequenzen von Fehlercodepunkten zu achten, die wieder in gültiges UTF-8 konvertiert werden, was von bösartiger Software verwendet werden kann, um unerwartete Zeichen in der Ausgabe zu erhalten, obwohl dies keine ASCII-Zeichen erzeugen kann, so dass dies berücksichtigt wird vergleichsweise sicher, da bösartige Sequenzen (wie Cross-Site-Scripting ) in der Regel auf ASCII-Zeichen angewiesen sind.

Siehe auch

Anmerkungen

Verweise

Externe Links