Was ist Unicode? Wenn man auf dem Bildschirm ein Zeichen sieht, was steckt dann wirklich dahinter? Zwei Dinge muss man dazu wissen:
Für den "oberen" Bereich, 128-255, gibt es keine international einheitliche Festlegung. (Eine umfassende und sogar unterhaltsame Geschichte der Computer-Codierungen schrieb Tom Jennings.) Hier ist die vollständige ASCII-Tabelle: Diese
Tabelle, aber sonst so
gut wie nichts, haben bis heute alle Computersysteme gemeinsam. Der
Industriestandard betrifft
nur die Werte bis 126, wie oben zu sehen, wobei die Werte 0 bis 31
und 127 Steuerfunktionen haben, also nicht für "richtige" Zeichen zur
Verfügung
stehen (und wenn, dann ungenormt). Die Codes 13 und 10 z.B. stehen traditionell für
"Wagenrücklauf" und
"Zeilenvorschub" - das stammt aus der Zeit der mechanischen
Endgeräte
(z.B. Fernschreiber und Zeilendrucker), aber noch immer dienen diese
Zeichen als Zeilentrenner in vielen Dateien. Das soll hier nicht
vertieft werden. Nur soviel: UNIX verwendet nur die 10,
Windows die Kombination 13 10, Mac nur die 13. Als Ausweg aus dem Dilemma gilt seit einiger Zeit das System "Unicode", das von einer internationalen Körperschaft, dem "Unicode Consortium", erarbeitet wurde und betreut wird: http://www.unicode.org. Wie
wurde Unicode
konstruiert? Man ordnete diese Zeichen dann sinnvoll in Gruppen, wobei an den Anfang die 128 Zeichen des ASCII-Codes gesetzt wurden, und zwar in derselben Reihenfolge. Dann numerierte man die Liste durch. Mit Bytes hat das noch nichts zu tun! Will man aber nun Texte speichern, die aus diesem Zeichenvorrat bestehen, dann muss man letztendlich doch alles irgendwie mit Hilfe von Bytes (mit je 8 Bit) ausdrücken – anders geht es nicht. Zwangsläufig muss man für jedes Zeichen zwei oder noch mehr Bytes verwenden - die alte Gleichung Zeichen=Byte ist untauglich. Zum Verschlüsseln der vielen Nummern mit Hilfe von Bytes wurden verschiedene Möglichkeiten ersonnen: Nachteil: Alte, "ganz normale" Dateien ohne Sonderzeichen brauchen dadurch doppelt soviel Platz wie bisher. 2.
Gemischte
Methoden : Nur 1 Byte für die
ASCII-Codes von 0 bis 127,
mehr
als eins für die anderen Zeichen. 2a. Codierungen der Gestalt &#N; (sog. Entitäten,
manchmal fälschlich
UTF-7 genannt), N
ist die Nummer des Zeichens: man nimmt also die Liste der
Unicode-Nummern und speichert das Zeichen 128 als €, 129 als
usw.
Moderne Browser verstehen das und zeigen dann die korrekten Zeichen. 2b.
UTF-8 : Man stellt
eine weitere Liste auf, wobei jeder Zahl jenseits 127 zwei Zahlen
zugeordnet werden, die erste muss oberhalb 191, die zweite
oberhalb 127
liegen. Das Zeichen 228 bekommt dabei dann die beiden Zahlen (195,164).
So kann es in einer Datei, die ja immer aus lauter Byte-Zahlen besteht,
keine Verwechslungen geben. Jedes Sonderzeichen wird auf diese Weise
als 2 Byte gespeichert, einige Sonderzeichen (z.B. Euro = E2 82 AC) und
alle ostasiatischen Zeichen bekommen 3 Bytes, darauf gehen wir hier
nicht ein. Programme, die damit umgehen, müssen beachten,
dass Codes
oberhalb 191 immer mit dem nachfolgenden Code zusammen ein Zeichen
bilden, Codes oberhalb 223 mit den zwei
nachfolgenden Bytes.
Die
zweiten und dritten Bytes liegen immer zwischen 128 und 191. Tip: Geben Sie in a99 den Befehl h chara ein, dann sehen Sie die bisher intern verwendeten Codes. Welche Methode ist die beste? Das kommt auf die Daten an, die man zu verarbeiten hat. Bestehen diese überwiegend aus normalen Buchstaben, Ziffern und Satzzeichen, dann ist es Methode 2b. Hat man vorwiegend ostasiatische Zeichen, dann Methode 1. Der Platzbedarf gilt heute nicht mehr als gravierend, es kommt aber auch auf die Probleme der Verarbeitung an. Methode 1 würde bedeuten, dass alle Programme auf 16bit-Zeichencodes umgestellt werden müssten und alle Dateien wären zu konvertieren, jede Daten- oder Indexdatei würde sich dabei in der Größe verdoppeln. Es ist jedoch wegen des hohen Programmieraufwands illusorisch, allegro auf diese Methode umzustellen. (In den Programmen wird mit vielen 8-bit-Zeichenkettenvariablen gearbeitet, und viele Funktionen gehen damit um. Dieses alles müsste umgestellt werden.) Die Methode 2a hat dagegen entscheidende Vorzüge, denn besonders in Web-Anwendungen lässt sich damit am leichtesten arbeiten: die heutigen Browser können diese Verschlüsselungen sofort verstehen und umsetzen. Will man 2b anwenden, muss in allen HTML-Dateien die folgende Zeile im <head>-Bereich stehen: <meta http-equiv="content-type" content="text/html; charset=UTF-8"> Dann werden aktuelle Browser die meisten Zeichen richtig anzeigen (Netscape 4.x nicht!), und zwar sowohl die Codierungen der Methode 2b wie auch 2a! Jedoch: wenn man mit einem HTML-Formular eine Eingabe speichert, d.h. zu einem Server abschickt, kommen Codes nach Methode 2b dort an. Wenn man auf der Seite des Servers wenig Arbeit haben will, sind also diese Codierungen von Vorteil. Soll man aber tatsächlich künftig jedes ä in der Datenbank als ä speichern oder als (195,164)? Das wäre wenig erfreulich, auch weil das erstere deutlich mehr Bytes braucht als vorher: 6 statt einem für jeden Umlautbuchstaben. Schlimmer noch, weil es in beiden Fällen viel schwieriger ist, daraus für den Index wieder "ae" zu machen oder in der PRESTO- bzw. a99-Anzeige ein ä, zu schweigen vom Eingeben und Bearbeiten in diesen Programmen. Indexierung und Anzeige konnten dennoch sowohl für 2a wie 2b gelöst werden: siehe dazu "VS-Methode" bzw. "P/Q-Tabelle". Eine
Besonderheit muss
noch erwähnt werden: Wenn man Buchstaben mit Akzenten braucht,
die im
normalen Vorrat nicht vorkommen, dann ist es im OstWest-Code so,
dass
man das diakritische Zeichen VOR den Buchstaben setzt. Unicode will es
umgekehrt, wobei aber fast alle Kombinationen schon als Einzelzeichen
definiert sind, sogar sehr viele Buchstaben mit zwei Diakritika! Unicode
aus
bibliothekarischer Sicht Die
zwei Varianten der
Unicode-Anwendung in allegro-Datenbanken
(ab V23.2)
Die PHP-Web-Schnittstellen PHPAC und a35 können auch Unicode. Export Schon
mit den bisherigen
Mitteln (p/q-Befehle) lassen sich sowohl "Entitäten" wie auch
UTF-8-Codes erzeugen. pa=181 182 183 184 189 190 198 199 207 208 209 210 211 212 219 222 223 232 Empfehlung:
Kopieren Sie
diese Zeile in Ihre Indexparameter, dann gilt sie überall da,
wo es
drauf ankommt. Bei Verwendung in IMPORT.EXE: Einbau in die benutzten
Exportparameter.
Anzeigeparameter Die heutigen Browser zeigen UTF-8-Codes korrekt an, d.h. hier ist angenehm wenig zu tun, es ist keine Umwandlungstabelle nötig. (PHPAC arbeitet in jedem Fall mit UTF-8, braucht deshalb für den OstWest-Code eine Tabelle: d-utf8.apt ).In a99 muss man in die Anzeigeparameter die Datei du-rtf.apt einbinden, damit man wenigstens im Anzeigefeld z.B. echte kyrillische Zeichen zu sehen bekommt. Darin stehen Zeilen wie P 208 144 "\u1041?" [0411] -- Б womit das kyrillische Б in RTF codiert werden kann. Im Datensatz wird dadurch die Bytekombination 208 144 durch \u1041? ersetzt. Die 1041 ist dieselbe Zahl, die in der HTML4-Entität Б auftritt. Import Damit man damit keine Probleme hat, sind folgende Vorkehrungen nötig:
Die
umzuwandelnden UTF-Codes
müssen in u-Befehlen stehen, ebenfalls in einer der
verwendeten
Export-Parameterdateien. (Empfehlung für
a99:
Indexparameterdatei, denn diese wird in jedem Fall geladen.) Diese
u-Zeilen, es können bis zu 800 Stück sein, sehen so
aus: u zzz yyy xxx bbb aaa Kommentar zzz
yyy xxx sind
die dezimalen UTF-8-Codes
des Zeichens. Wenn zzz<224 ist, dann fehlt xxx, was bedeutet,
dass
es sich um einen 2-Byte-UTF-8-Code handelt. bbb ist der OstWest-DOS-Code, aaa wird nur angegeben, und muss dann einer der DOS-Akzentcodes sein (siehe oben im pa-Befehl), wenn auf allegro-Seite der akzentuierte Buchstabe als Einzelzeichen nicht existiert, wie z.B. Á und ã. Die u-Befehle werden nur für die Umwandlung von Fremddaten benutzt, nicht für den Export. Also i.d.R. beim Einlesen einer ADT-Datei, die in UTF-8 codiert ist, bzw. beim Übergeben von HTML-Formulardaten an den avanti-Server, oder auch im DOS-Konvertierprogramm IMPORT.EXE. Im
FLEX setzt man vor die
Befehle zum Einlesen der Daten den Befehl set U1 , dahinter set U0. Achtung:
Das Vertauschen von
Akzenten und Buchstaben erfolgt dabei automatisch im Anschluss
an das
Umwandeln der Codes (beim FLEX-Befehl insert)
. Für das Programm IMPORT setzt man die u-Befehle in die dabei benutzten Exportparameter (!), dann passiert die Umwandlung ganz automatisch, und zwar jeweils beim Einordnen eines fertigen Datenfeldes in den entstehenden Datensatz. Außerdem gehört in die Exportparameter der Befehl #dA. Die Befehle in den Paragraphen der Importparameter "sehen" deshalb noch die nicht umgewandelten Daten! Wir haben dank der Hilfe von Thomas Berger eine u-Liste von ca. 300 akzentuierten Buchstaben erstellt, die als Datei ucodes.txt mit V23 mitgeliefert wird. Berger hat auf seinem Server weitere empfehlenswerte Materialien und relevante Dokumentationen: weitere u-Codes findet man in mit Kommentar in einer Datei uc-ow.cpt. Oder man benutzt das besagte Progrämmchen. Nicht
berücksichtigt sind
Kombinationen von Buchstaben mit zwei Diakritika,
deren es im
Unicode durchaus etliche gibt. Solche werden also in die
Entitäts-Darstellung verwandelt. Export Wenn
man "Entitäten" in den
eigenen Daten (innerhalb der Datenbank also) verwenden will, sollte man
die "Stammdatei" vs.alg zuerst einmischen. Damit
diese Daten
korrekt indexiert werden, muss man die entsprechenden
Abschnitte aus
cat.api in die eigenen Indexparameter übernehmen (darin
Kommentar
"V23"). In
den Exportparametern wird
man normalerweise #dV setzen (zu empfehlen
in
Indexparametern), dann werden alle Ersetzungen zu dem Zeitpunkt auf
einmal ausgeführt, und nachfolgende Exportbefehle sehen nur
noch die
ersetzten Zeichen! Export
mit dem Befehl
"write ..." ( in a99 und avanti) 1. in die benutzten Exportparameter diesen Abschnitt einbauen: zl=0
kein Zeilenumbruch 2.
Im FLEX vor dem
"write"-Befehl diese Befehle einbauen
Eingabe-Unterstützung für Verfahren 1 Die
VS-Stammsätze dienen
zugleich dazu, Indexeinträge bereitzustellen, die man zum
Suchen und
Übernehmen der "Entitäten" verwenden kann. Im
Übernahme-Register steht
dann z.B. unter u diese Liste: Man gibt z.B. "kyr a" ein, um zu dem Abschnitt der kyrillischen Kleinbuchstaben zu kommen. In die Standard-Parameter cat.api sind die nötigen Zusätze eingebaut, kommentiert mit "V23", damit man sie leicht findet und in andere Indexparameter übernehmen kann.
Für das Umwandeln von UTF-8-Codes in Entitätenzahlen für RTF- oder HTML-Dateien gibt es ab V29.3 einen FLEX-Befehl xcode U... (Geben Sie in a99 ein h xcode) Dabei kommen intern einige einfache Formeln zum Einsatz, die im Anhang dokumentiert sind. Web-Schnittstelle
(für beide
Verfahren
gültig) Dies
ist die XP-Version! Unter
NT und '98 gibt es erheblich weniger Möglichkeiten. |
Anhang : Umrechnung UTF-8 -> Dezimal-Entitätencode E Normalerweise machen Programmierer das mit geschickten Bitmanipulationen, weil die intern schneller gehen. Z.B. bedeutet "-128" dann soviel wie das Wegnehmen des siebten Bits, und "*64" ist ein Verschieben um 6 Bit nach links. Hier wird statt dessen gezeigt, wie man es in anschaulich schlichter (dafür intern viel langsamerer) Weise mit Dezimalzahlen machen kann. Situation: Bei zeichenweiser Abarbeitung eines Unicode-Textes von links nach rechts trifft man plötzlich auf einen Code a >193, dann: Wenn a>193 und a<224 U+0080 - 07ff Dann ist 127 < E < 2048 128 - 2047 Mit dem auf a folgenden Zeichen b zusammen ergibt sich: (Wert b ist stets >127 und <192) +--------------------------------+ | E = (a-196)*64 + b-128 + 256 | +--------------------------------+ und damit RTF: \uE? bzw, HTML4: &#E; Beispiele: Die niedrigste Entitätenzahl ist 128 a b 194 128 E= (194-196)*64 +(128-128) +256 = 128 = U+0080 Die höchste der zweistelligen UTF-Codes ist 2047: a b 223 191 E= (223-196)*64 +(191-128) +256 = 2047 = U+07ff Das gilt nur bis a=223. Danach kommen die 3-Byte-Codes: Wenn 223 < a < 240 ( ab U+0800 ) Dann ist 2047 < E < 65536 Man nimmt dann die ZWEI auf a folgenden Codes b, c, wobei 127 < b,c < 224 gelten muss. a b c 224 160 128 bis 239 191 191 0800 - ffff e0 a0 80 ef bf bf 2048 - 65535 E = (a-224)*4096 +(b-128)*64 +(c-128) 0 32 0 = 2048 z.B. Euro-Zeichen: 226 130 172 U+20ac 2*4096 + 2*64 + (172-128) = 8364 Hilfreiche Adresse: http://titus.uni-frankfurt.de/indexd.htm?/unicode/unitest.htm Umgekehrte Rechnung: Entitätenzahl -> UTF-8 Gegeben ist eine Dezimalzahl E Im folgenden wird beim Dividieren stets nur der ganzzahlige Teil genommen, mit % wird der Divisionsrest gebildet: 1. Fall
127 < E < 256:
a = (E-256-63)/64 + 196
b = E%64 + 128 (Divisionsrest)
2. Fall 127 < E < 2048: a = (E-256)/64 + 196 b = (E-256)%64 + 128 (Divisionsrest) 3. Fall 2047 < E < 65536 a = E/4096+224 b = (E-(a-224)*4096)/64 +128 c = (E-(a-224)*4096-(b-128)*64)+128 z.B. E = 8364: a = E/4096 +224 = 2 + 224 = 226 b = (E-2*4096)/64 +128 = 172/64 +128 = 2 +128 = 130 c = (E-2*4096 -2*64) +128 = 44 + 128 = 172 |
B.Eversberg
, UB
Braunschweig, 2003-02-18 / 2022-02-05