Standard Compression Scheme for Unicode

Codierungsschema für Unicode-Zeichen

Das Standard Compression Scheme for Unicode (SCSU, englisch für Standard-Kompressions-Schema für Unicode) ist eine Zeichenkodierung für Texte aus Unicode-Zeichen, das im Gegensatz zu den meisten anderen Kodierungen darauf ausgerichtet ist, möglichst wenig Speicherplatz zu benötigen.

Geschichte

Bearbeiten

Die Kodierung wurde ursprünglich von Reuters entwickelt. Autoren des im technischen Standard UTS #6 beschriebenen Verfahrens sind Misha Wolf, Ken Whistler, Charles Wicksteed, Mark Davis, Asmus Freytag und Markus Scherer. Die erste Veröffentlichung erfolgte im Mai 1997,[1] seit Mai 2005 liegt der Standard unverändert in der Revision 4 vor.

Traditionelle Zeichensätze vor Unicode, etwa die ISO-8859-Zeichensätze, benötigten nur ein Byte pro Zeichen, Zeichensätze für ostasiatische Schriften zwei Byte. Bei der Verwendung von Unicode steigt der Speicherbedarf meist an: Bei UTF-32 auf vier Byte pro Zeichen, bei UTF-16 sind es zwei oder vier Byte pro Zeichen, bei UTF-8 zwischen ein und vier Byte pro Zeichen. Dabei nutzen gewöhnliche Texte nur einen sehr kleinen Teil aller in Unicode verfügbaren Zeichen. Die meisten verwendeten Zeichen liegen dabei zum einen im ASCII-Bereich (insbesondere Satzzeichen), zum anderen in einem kleinen zusammenhängenden Bereich, der häufig einem Unicodeblock entspricht. Der Algorithmus verwendet ein dynamisch positioniertes Fenster, das 128 aufeinander folgende Zeichen umfasst. Zeichen in diesem Fenster werden durch ein Byte im Bereich von 0x80 bis 0xFF kodiert, Zeichen im ASCII-Bereich (mit Ausnahme der meisten Steuerzeichen) durch ein Byte aus dem Bereich von 0x20 bis 0x7F. Die restlichen Byte werden als Befehle verwendet, um dieses Fenster neu zu positionierten oder in den unkomprimierten Modus umzuschalten, in dem die folgenden Byte als UTF-16 interpretiert werden. Dieser Modus ist besonders dann zweckmäßig, wenn der Text viele Zeichen aus einem Bereich von mehr als 128 aufeinander folgenden Zeichen verwendet, etwa im Chinesischen.

Algorithmus

Bearbeiten

Diese Idee wird mit dem folgenden Verfahren umgesetzt. Definiert wird dabei die Methode, mit der aus einem SCSU-Bytestrom wieder ein Text aus Unicode-Zeichen gewonnen werden kann. Zur Kodierung können verschiedene Algorithmen verwendet werden, die zu einem Ergebnis führen, das korrekt dekodiert werden kann. Wie ein solcher Algorithmus gestaltet wird, hängt unter anderem davon ab, ob mehr Gewicht auf eine schnelle Kodierung oder auf eine gute Kompression gelegt wird.

Der Algorithmus kennt zwei Arten von Fenstern: Statische Fenster, die im Algorithmus fest vordefiniert sind, und dynamische Fenster, deren Position bei Bedarf geändert werden kann. Von jeder Sorte gibt es acht Stück, nummeriert von 0 bis 7. Die Lage eines Fensters kann durch den Codepunkt des ersten Zeichens in diesem Fenster angegeben werden.

Statische Fenster

Bearbeiten

Die acht statischen Fenster sind folgendermaßen definiert:

Fensternummer Start enthaltene Zeichen
0 U+0000 Basis-Lateinisch
1 U+0080 Lateinisch-1, Ergänzung
2 U+0100 Lateinisch, erweitert-A
3 U+0300 Kombinierende diakritische Zeichen
4 U+2000 Allgemeine Interpunktion und Hochgestellte Zeichen
5 U+2080 Tiefgestellte Zeichen, Währungszeichen und Kombinierende diakritische Zeichen für Symbole
6 U+2100 Buchstabenähnliche Symbole und Zahlzeichen
7 U+3000 CJK-Symbole und -Interpunktion

Dynamische Fenster

Bearbeiten

Die Anfangspositionen der acht dynamischen Fenster sind die folgenden:

Fensternummer Start enthaltene Zeichen
0 U+0080 Lateinisch-1, Ergänzung
1 U+00C0 Teile von Lateinisch-1, Ergänzung und Lateinisch, erweitert-A
2 U+0400 Kyrillisch
3 U+0600 Arabisch
4 U+0900 Devanagari
5 U+3040 Hiragana
6 U+30A0 Katakana
7 U+FF00 Vollbreite Formen

Das dynamische Fenster 0 ist dabei zu Beginn aktiv.

Um die Position eines dynamischen Fensters zu verändern, stehen verschiedene Befehle zur Verfügung. Die beiden einfachen Befehle (SDn und UDn) zur Definition bestimmen die neue Lage des Fensters durch ein Byte nach der folgenden Tabelle:

Byte
(hex)
Start Anmerkung
00 reserviert reserviert zur internen Verwendung
01–67 U+0080–U+3380 das Byte wird mit 0x80 multipliziert
68–A7 U+E000–U+FF80 das Byte wird mit 0x80 multipliziert, dazu wird 0xAC00 addiert
A8–F8 reserviert reserviert für zukünftige Verwendung
F9 U+00C0 Teile von Lateinisch-1, Ergänzung und Lateinisch, erweitert-A
FA U+0250 IPA-Erweiterungen
FB U+0370 Griechisch
FC U+0530 Armenisch
FD U+3040 Hiragana
FE U+30A0 Katakana
FF U+FF60 Halbbreite Katakana

Die beiden erweiterten Befehle (SDX und UDX) zur Fensterdefinition verwenden zwei Byte. Die obersten drei Bit geben die Nummer des Fensters an, zu den restlichen 13 Bit wird 0x10000 addiert und das Ergebnis als erstes Zeichen des Fensters genommen.

Der Algorithmus verwendet zwei verschiedene Modi. Anfangs befindet er sich im Ein-Byte-Modus, in dem Zeichen durch ein einzelnes Byte kodiert werden. Bytewerte im Bereich 0x20 bis 0x7F sowie 0x00 (NUL), 0x09 (horizontales Tabulatorzeichen), 0x0A (LF) und 0x0D (CR) werden als Zeichen im statischen Fenster 0 interpretiert, Werte im Bereich 0x80 bis 0xFF als Zeichen im aktiven dynamischen Fenster. Alle anderen Byte werden als Befehle interpretiert.

Der andere Modus ist ein Zwei-Byte-Modus. Bis auf einige Ausnahmen werden hier alle Bytepaare als UTF-16BE-kodierte Zeichen interpretiert, nur einige wenige Bytes stellen Befehle dar.

Im Ein-Byte-Modus stellen folgende Bytewerte Befehle dar:

Byte
(hex)
Name Bedeutung
01–08 SQ0–SQ7 wechselt für das folgende Byte die Fenster: 0x00 bis 0x7F werden als Zeichen im statischen Fenster n interpretiert, 0x80 bis 0xFF im dynamischen Fenster n
0B SDX verwendet die beiden folgenden Bytes zur erweiterten Definition eines dynamischen Fensters, dieses Fenster ist danach aktiv
0C reserviert reserviert für zukünftige Verwendung
0E SQU interpretiert die beiden folgenden Byte als ein UTF-16-kodiertes Zeichen
0F SCU wechselt in den Zwei-Byte-Modus
10–17 SC0–SC7 macht das dynamische Fenster n zum aktiven Fenster
18–1F SD0–SD7 verwendet das folgende Byte als einfache Definition für das dynamische Fenster n, dieses Fenster ist danach aktiv

Soll ein Steuerzeichen kodiert werden, das durch ein Byte repräsentiert wird, das einen Befehl darstellt, kann der Befehl SQ0 verwendet werden.

Im Zwei-Byte-Modus stellen folgende Bytewerte Befehle dar, sofern sie an erster Position in einem möglichen Bytepaar auftreten:

Byte
(hex)
Name Bedeutung
E0–E7 UC0–UC7 wechselt in den Ein-Byte-Modus und aktiviert das dynamische Fenster n
E8–EF UD0–UD7 verwendet das folgende Byte als einfache Definition für das dynamische Fenster n, aktiviert dieses Fenster und wechselt in den Ein-Byte-Modus
F0 UQU interpretiert die beiden folgenden Byte als ein UTF-16-kodiertes Zeichen
F1 UDX verwendet die beiden folgenden Byte zur erweiterten Definition eines dynamischen Fensters, aktiviert dieses Fenster und wechselt in den Ein-Byte-Modus
F2 reserviert reserviert für zukünftige Verwendung

Soll ein Zeichen (aus dem Bereich zur privaten Nutzung) kodiert werden, das mit einem von einem Befehl besetzten Byte beginnt, kann der Befehl UQU verwendet werden.

Eigenschaften

Bearbeiten

Das Verfahren besitzt einige Eigenschaften, die bewusst gewählt wurden:

  • Für Texte, die ausschließlich aus Latin-1-Zeichen ohne Steuerzeichen bestehen, ergibt sich keine Änderung.
  • Für Texte ohne Zeichen aus dem Bereich zur privaten Nutzung kann immer mit einem zusätzlichen Byte in den Zwei-Byte-Modus umgeschaltet werden, sodass der Speicherbedarf in diesem Fall dem von UTF-16 entspricht.
  • Selbst im schlechtesten Fall ist der Speicherbedarf nur um einen Faktor 1,5 größer als UTF-16.
  • Bei optimaler Kodierung werden normale Texte kompakter als in UTF-8 oder UTF-16 gespeichert. Wie groß diese Einsparung ist, hängt von der Sprache ab: Während bei englischen und französischen Texten SCSU genauso viel Platz benötigt wie UTF-8, reduziert sich dieser bei Koreanisch auf 85 %, bei Chinesisch auf 70 %, bei Griechisch, Russisch, Arabisch, Hebräisch und Japanisch auf 55 %, bei Hindi sogar auf 40 %.[2]

Folgende Eigenschaften können in einigen Anwendungen problematisch sein:

  • Im komprimierten Bytestrom können Null-Byte vorkommen, unter anderem deswegen ist die Kodierung nicht MIME-kompatibel. Hier kann stattdessen BOCU-1 verwendet werden.
  • Der gleiche Text kann auf unterschiedliche Art kodiert werden.
  • Texte mit wenigen verschiedenen Zeichen, die aber auf mehrere unzusammenhängende Bereiche verteilt sind, können nicht gut komprimiert werden. Dies ist etwa im Vietnamesischen der Fall.

Mögliche Kodierungen

Bearbeiten

Folgen von Zeichen aus dem ASCII-Bereich und den vordefinierten dynamischen Fenstern werden am effizientesten im Ein-Byte-Modus kodiert. Gibt es kein geeignetes vordefiniertes Fenster, so kann ein nicht benötigtes dynamisches Fenster umdefiniert werden. Von den chinesischen und koreanischen Schriftzeichen abgesehen, können die meisten Bereiche als dynamisches Fenster gewählt werden.

Für Folgen von Zeichen außerhalb kleiner Bereiche sollte in den Zwei-Byte-Modus umgeschaltet werden.

Einzelne Zeichen, die in einem Fenster liegen, das gerade nicht aktiv ist, können über den Befehl SQn kodiert werden, Einzelzeichen außerhalb der möglichen Fenster über den Befehl SQU.

Beispiele

Bearbeiten

Um den Text „Wikipedia – die freie Enzyklopädie“ (mit typographischem Gedankenstrich) mit SCSU zu kodieren, reichen alle vordefinierten Fenster aus: nur der Gedankenstrich und das ä liegen nicht im ASCII-Bereich. Das ä befindet sich im aktiven dynamischen Fenster, der Gedankenstrich im statischen Fenster 4. Es ergibt sich also folgende hexadezimale Bytefolge:

57 69 6B 69 70 65 64 69 61 20 05  13 20 64 69 65 20 66 72 65 69 65 20
W  i  k  i  p  e  d  i  a     SQ4 –     d  i  e     f  r  e  i  e
45 6E 7A 79 6B 6C 6F 70 E4 64 69 65
E  n  z  y  k  l  o  p  ä  d  i  e

Bis auf den Gedankenstrich stimmt die Kodierung mit ISO 8859-1 überein.

Griechisch

Bearbeiten

Alle Zeichen des griechischen Wortes für Wikipedia „Βικιπαίδεια“ liegen im Unicodeblock für Griechisch. Es lässt sich daher kodieren, indem erst dieser Block durch ein dynamisches Fenster abgedeckt wird, mit dessen Hilfe dann die Buchstaben kodiert werden.

18  FB A2 C9 CA C9 D0 C1 BF C4 C5 C9 C1
SD0    Β  ι  κ  ι  π  α  ί  δ  ε  ι  α

Die Kodierung braucht nur zwei Byte mehr als ISO 8859-7, ist aber gegenüber dieser um 0x20 verschoben.

Japanisch

Bearbeiten

Der japanische Wikipedia-Artikel über Wikipedia beginnt folgendermaßen:

„ウィキペディア(英: Wikipedia)は、ウィキメディア財団が運営するインターネット百科事典である。“

Wikipedia-Autoren: „ウィキペディア“ in der Version vom 26. Januar 2013

Es werden dabei verschiedene Schriften verwendet:

  • Lateinische Buchstaben und Satzzeichen, die im statischen Fenster 0 liegen
  • Katakana aus dem dynamischen Fenster 6
  • vereinzelt Hiragana aus dem dynamischen Fenster 5
  • CJK-Zeichen, die in keinem möglichen Fenster liegen
  • Vollbreite Satzzeichen aus dem dynamischen Fenster 7
  • CJK-Interpunktion aus dem statischen Fenster 7

Eine von vielen möglichen Kodierungen stellen die folgenden Tabellen dar: Die meiste Zeit wird mit dem dynamischen Fenster 6 (Katakana) gearbeitet. Einzelne Zeichen aus anderen Bereichen werden ohne einen dauerhaften Wechsel kodiert. Für längere Folgen von CJK-Zeichen wird dabei in den Zwei-Byte-Modus gewechselt, erst wenn wieder längere Folgen von Hiragana oder Katakana kodiert werden müssen, wird in den Ein-Byte-Modus zurückgeschaltet.

Byte 16 86 83 8D BA A7 83 82 08 88 0E 82 F1 3A 20 57 69 6B 69 70 65 64 69 61 08 89
Zeichen
Befehl
SC6 SQ7 SQU :   W i k i p e d i a SQ7
Codepunkt (U+)   30A6 30A3 30AD 30DA 30C7 30A3 30A2   FF08   82F1 003A 0020 0057 0069 006B 0069 0070 0065 0064 0069 0061   FF09
Byte 06 AF 08 01 86 83 8D C1 A7 83 82 0F 8C A1 56 E3 30 4C 90 4B 55 B6
Zeichen
Befehl
SQ5 SQ7 SCU
Codepunkt (U+)   306F   3001 30A6 30A3 30AD 30E1 30C7 30A3 30A2   8CA1 56E3 304C 904B 55B6
Byte E5 99 CB 16 84 D3 9F DC AC A3 A8 0F 76 7E 79 D1 4E 8B 51 78 E5 A7 82 CB 08 02
Zeichen
Befehl
UC5 SC6 SCU UC5 SQ7
Codepunkt (U+)   3059 308B   30A4 30F3 30BF 30FC 30CD 30C3 30C8   767E 79D1 4E8B 5178   3067 3042 308B   3002

Verwendung

Bearbeiten

In der Praxis konnte sich SCSU nie durchsetzen. Nur einige wenige Programme verwenden diese Kodierung, darunter Microsoft SQL Server[3] und Symbian.[4]

Eines der Hauptprobleme des Verfahrens ist es, einen guten Algorithmus zum Komprimieren zu finden und diesen auszuführen. Da es meist effizienter ist Rechenzeit zu sparen als Speicherplatz, lohnt sich der Aufwand einer Komprimierung mit SCSU für die meisten Anwendungen nicht gegenüber UTF-8 oder UTF-16. Zudem führte die fehlende Unterstützung von SCSU in Anwendungsprogrammen dazu, dass SCSU kaum genutzt wurde, was wiederum dazu führte, dass die Kodierung auch weiterhin nicht unterstützt wurde. Da eine Fehlinterpretation durch Programme, die SCSU nicht unterstützen, zu unerwartetem Verhalten und sogar zu Sicherheitsproblemen führen kann, ist eine Verwendung von SCSU in HTML5 ausdrücklich ausgeschlossen.[5]

  • Asmus Freytag u. a.: Unicode Technical Standard #6: A Standard Compression Scheme For Unicode. (online)
  • Doug Ewell: Unicode Technical Note #14: A Survey of Unicode Compression. (online)

Einzelnachweise

Bearbeiten
  1. Asmus Freytag u. a.: Unicode Technical Standard #6: A Standard Compression Scheme For Unicode. Revision 1.0
  2. Gemessen an What is Unicode in verschiedenen Sprachen in: Markus W. Scherer, Mark Davis: Unicode Technical Note #6: BOCU-1. BOCU-1 Performance
  3. Unicode Compression Implementation, abgerufen am 26. Januar 2013.
  4. Forum Nokia Library: Compressed Unicode resource format@1@2Vorlage:Toter Link/library.developer.nokia.com (Seite nicht mehr abrufbar, festgestellt im Mai 2019. Suche in Webarchiven)  Info: Der Link wurde automatisch als defekt markiert. Bitte prüfe den Link gemäß Anleitung und entferne dann diesen Hinweis., abgerufen am 26. Januar 2013.
  5. HTML Standard: Character Encodings, abgerufen am 3. Dezember 2015.
Bearbeiten