Standard Compression Scheme for Unicode

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ötigten.

Geschichte

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.

Idee

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

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.

Fenster

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

Die acht statischen Fenster sind folgendermaßen definiert:

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

Dynamische Fenster

Die Anfangspositionen der acht dynamischen Fenster sind die folgenden:

FensternummerStartenthaltene Zeichen
0U+0080Lateinisch-1, Ergänzung
1U+00C0Teile von Lateinisch-1, Ergänzung und Lateinisch, erweitert-A
2U+0400Kyrillisch
3U+0600Arabisch
4U+0900Devanagari
5U+3040Hiragana
6U+30A0Katakana
7U+FF00Vollbreite 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)
StartAnmerkung
00reserviertreserviert zur internen Verwendung
01–67U+0080–U+3380das Byte wird mit 0x80 multipliziert
68–A7U+E000–U+FF80das Byte wird mit 0x80 multipliziert, dazu wird 0xAC00 addiert
A8–F8reserviertreserviert für zukünftige Verwendung
F9U+00C0Teile von Lateinisch-1, Ergänzung und Lateinisch, erweitert-A
FAU+0250IPA-Erweiterungen
FBU+0370Griechisch
FCU+0530Armenisch
FDU+3040Hiragana
FEU+30A0Katakana
FFU+FF60Halbbreite 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.

Modi

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 UFT-16BE-kodierte Zeichen interpretiert, nur einige wenige Bytes stellen Befehle dar.

Befehle

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

Byte
(hex)
NameBedeutung
01–08SQ0–SQ7wechselt 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
0BSDXverwendet die beiden folgenden Bytes zur erweiterten Definition eines dynamischen Fensters, dieses Fenster ist danach aktiv
0Creserviertreserviert für zukünftige Verwendung
0ESQUinterpretiert die beiden folgenden Byte als ein UTF-16-kodiertes Zeichen
0FSCUwechselt in den Zwei-Byte-Modus
10–17SC0–SC7macht das dynamische Fenster n zum aktiven Fenster
18–1FSD0–SD7verwendet 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)
NameBedeutung
E0–E7UC0–UC7wechselt in den Ein-Byte-Modus und aktiviert das dynamische Fenster n
E8–EFUD0–UD7verwendet das folgende Byte als einfache Definition für das dynamische Fenster n, aktiviert dieses Fenster und wechselt in den Ein-Byte-Modus
F0UQUinterpretiert die beiden folgenden Byte als ein UTF-16-kodiertes Zeichen
F1UDXverwendet die beiden folgenden Byte zur erweiterten Definition eines dynamischen Fensters, aktiviert dieses Fenster und wechselt in den Ein-Byte-Modus
F2reserviertreserviert 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

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

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

Deutsch

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

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

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.

Byte1686838DBAA7838208880E82F13A2057696B6970656469610889
Zeichen
Befehl
SC6SQ7SQU: WikipediaSQ7
Codepunkt (U+) 30A630A330AD30DA30C730A330A2 FF08 82F1003A002000570069006B006900700065006400690061 FF09
Byte06AF080186838DC1A783820F8CA156E3304C904B55B6
Zeichen
Befehl
SQ5SQ7SCU
Codepunkt (U+) 306F 300130A630A330AD30E130C730A330A2 8CA156E3304C904B55B6
ByteE599CB1684D39FDCACA3A80F767E79D14E8B5178E5A782CB0802
Zeichen
Befehl
UC5SC6SCUUC5SQ7
Codepunkt (U+) 3059308B 30A430F330BF30FC30CD30C330C8 767E79D14E8B5178 30673042308B 3002

Verwendung

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]

Quellen

  • 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

  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.

Weblinks