Zeichen, Codepunkte und Bytes

Unicode gibt jedem Zeichen jeder Schrift eine Nummer, den Codepunkt, geschrieben als U+ mit hexadezimalen Ziffern: A ist U+0041, ä U+00E4, das Eurozeichen U+20AC, das lächelnde Gesicht U+1F600. Es gibt über eine Million Positionen, etwa 150.000 davon belegt.

Der Codepunkt muss dann zu Bytes werden. UTF-8, die Kodierung des Webs, braucht ein bis vier Byte: eines für ASCII, zwei für Umlaute und Akzente, drei für fast alles andere, vier für Emoji und seltene Symbole. UTF-16, das JavaScript, Java und Windows nutzen, braucht zwei Byte oder ein Surrogatpaar aus vier.

Deshalb hängt die Länge einer Zeichenkette davon ab, was man zählt: "😀".length ist in JavaScript 2, in UTF-8 belegt das Zeichen 4 Byte, und fürs Auge ist es eines. Und ein Buchstabe mit Akzent kann ein einziger Codepunkt sein oder ein Buchstabe plus kombinierender Akzent: Sie sehen gleich aus, sind es aber nicht.

Häufige Fehler

  • Eine UTF-8-Zeichenkette nach einer festen Zahl von Bytes abschneiden: Ein Zeichen kann dabei zerteilt werden.
  • Zeichen in JavaScript mit .length zählen: Emoji und Zeichen außerhalb der Basisebene zählen doppelt.
  • Texte ohne Normalisierung vergleichen: Ein vorkomponiertes ä und a mit kombinierendem Trema sind für den Computer verschieden.

Häufige Fragen

Was ist der Unterschied zwischen Unicode und UTF-8?

Unicode ist die Liste der Zeichen mit ihren Nummern; UTF-8 ist eine Art, diese Nummern als Bytes zu schreiben. Derselbe Unicode-Text kann als UTF-8, UTF-16 oder UTF-32 gespeichert werden.

Warum sehe ich seltsame Zeichen wie ä statt ä?

Weil ein UTF-8-Text als Latin-1 gelesen wird: Die zwei Bytes von ä, C3 A4, werden zu zwei getrennten Zeichen. Die richtige Kodierung anzugeben behebt es.

Wie schreibe ich ein Unicode-Zeichen in HTML?

Mit einer numerischen Entität: ä dezimal oder ä hexadezimal. Ist die Seite in UTF-8, kannst du das Zeichen auch direkt eingeben.

So funktioniert diese Berechnung

UTF-8: bis U+007F ein Byte 0xxxxxxx; bis U+07FF zwei Bytes 110xxxxx 10xxxxxx; bis U+FFFF drei Bytes 1110xxxx 10xxxxxx 10xxxxxx; darüber vier Bytes 11110xxx und drei Folgebytes. UTF-16: bis U+FFFF eine 16-Bit-Einheit; darüber wird 0x10000 abgezogen und die 20 Bit auf zwei Surrogate verteilt, 0xD800 + die oberen 10 Bit und 0xDC00 + die unteren 10.