Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Versteht hier jemand Unicode? (https://www.delphipraxis.net/156869-versteht-hier-jemand-unicode.html)

Luckie 18. Dez 2010 07:17

Versteht hier jemand Unicode?
 
Also ich dachte, ich beschäftige mich mal etwas mit Unicode. Ich habe mir dazu die entsprechenden Wikipedia Artikel rausgesucht (UTF-8, UTF-16, UTF-32) und bin zu dem Schluss gekommen, wie kann ein menschliches Gehirn so etwas produzieren?

UTF-32 ist ja kein Problem, da ist jedes Zeichen mit vier Byte kodiert. Also analog zu ASCII mit einem Byte. OK, verstanden. Aber bei UTF-8 und 16 hat es dann bei mir ausgesetzt. Versteht das einer von euch und kann das in klar verständlichen, einfachen Worten erklären? Ich kann es nicht.

Matze 18. Dez 2010 07:25

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von Luckie (Beitrag 1069199)
Aber bei UTF-8 und 16 hat es dann bei mir ausgesetzt. Versteht das einer von euch und kann das in klar verständlichen, einfachen Worten erklären? Ich kann es nicht.

Was verstehst du denn genau nicht? Anhand der ersten 1 - 2 Bits jedes Bytes kannst du herausfinden, ob es ein Start-Byte oder ein Folgebyte ist (ähnlich einer Art Header, der pro Byte verwendet wird). Siehe hier. Somit kannst du anhand dieser 1 - 2 Bits jedes Bytes abfragen, ob ein neues Zeichen beginnt oder ob das Byte noch zum alten Zeichen gehört.

Als Vorteil vermute ich eine geringere Größe des Texts, sofern z.B. nur ASCII-Zeichen verwendet werden. Sonst wäre der Text 4 x so groß beim gleichen Informationsgehalt.

Luckie 18. Dez 2010 07:36

AW: Versteht hier jemand Unicode?
 
Genau die verlinkte Tabelle hat mich verwirrt. Also wenn das Byte mit 0 anfängt ist das Zeichen auch in dem Byte kodiert. Fängt das Byte mit 11 an ist es das Startbyte und es gibt noch ein Folgebyte. Das oder die Folgebyte(s) fangen immer mit 10 an. Die Anzahl der Einsen am Anfang den Startbytes geben die Anzahl der Bytes an mit dem ein Zeichen kodiert ist. Also 111 bedeutet, dass es das Startbyte ist und noch zwei Folgebytes kommen. Dabei sind die Einsen immer mit einer null von den andern Bits, die das Zeichen kodieren, abgetrennt.
Beispiel: 110xxxxx 10xxxxxx oder 1110xxxx 10xxxxxx 10xxxxxx.

Kann man das so zusammenfassen? Wenn ja habe ich UTF-8 schon mal verstanden. Bleibt noch UTF-16.

Matze 18. Dez 2010 07:51

AW: Versteht hier jemand Unicode?
 
So steht's zumindest auf Wikipedia. Wenn das stimmt, was dort steht, hast du es schön kurz zusammengefasst und es passt, würde ich sagen.

Die PDF zu UTF-16 ist mir zu umfangreich, um sie mal eben durchzulesen. Wie UTF-16 funktioniert, kann ich dir nicht sagen. Ich habe es selbst auch nie verwendet.

Luckie 18. Dez 2010 07:55

AW: Versteht hier jemand Unicode?
 
UTF-16 kommt heute Nachmittag dran. ;)

himitsu 18. Dez 2010 09:38

AW: Versteht hier jemand Unicode?
 
Delphi-Referenz durchsuchenIsLeadByte

Außerdem ist UTF-8 doch recht einfach?
7. Bit nicht gesetzt (... and $80 = 0) = entspricht ASCII
7. Bit gestzt (... and $80 <> 0), es handelt sich um einen Teil von was Kodiertem
7. und 6. Bit gesetzt (... and $C0 = $C0) = Führungsbyte / Leading Byte
7. gesetzt und 6. nicht (... and $C0 = $80) = Folgebyte / Trailing Byte

Und die Anzahl der führenden Bits, des Führungsbytes, natürlich gefollgt von einem 0-Bit, gibt die Anzahl der Bytes in der Gruppe an (oder man nimmt einfach nur die nachfolgenen Folgebytes dazu und prüft nur auf dessen Muster).

http://de.wikipedia.org/wiki/UTF-8#Kodierung

PS: Das Unicode in Delphi/Windows entspricht dem UTF-16.

Matze 18. Dez 2010 09:39

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von himitsu (Beitrag 1069213)
Außerdem ist UTF-8 doch recht einfach?

Das hat Michael längst verstanden, wie den vergangenen Beiträgen zu entnehmen ist. :tongue:

Aber du bist doch Unicode-Experte. Erkläre mal, wie UTF-16 funktioniert. ;)

himitsu 18. Dez 2010 10:06

AW: Versteht hier jemand Unicode?
 
Wenn du diese blöden Surrogate-Pairs ignorierst, dann ist UTF-16 quasi uncodiert und man kann die Werte der Words/Chars direkt verwenden. :angle2:

Assarbad 18. Dez 2010 12:49

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von himitsu (Beitrag 1069219)
Wenn du diese blöden Surrogate-Pairs ignorierst, dann ist UTF-16 quasi uncodiert und man kann die Werte der Words/Chars direkt verwenden. :angle2:

Aber genau das kann man nicht mehr machen, seitdem Unicode mehr als 64k Zeichen enthält. Was du meinst ist UCS-2 (wie es von NT anfangs unterstützt wurde).

Aber stimmt schon. In den meisten Fällen mit denen wir es zu tun bekommen werden, wird die in UCS-2 getroffene Annahme 16bit == 1 Kodepunkt schon stimmen.

Ansonsten gibt es ein feines Buch von O'Reilly zum Thema. Kann es empfehlen.

himitsu 18. Dez 2010 13:05

AW: Versteht hier jemand Unicode?
 
Es kommt drauf an, wenn man eh nicht viel macht und die SurrogatePairs wie "normale" Zeichen behandelt und sie nicht anfaßt/verändert, dann kann doch eigentlich nichts passieren.
Selbst Delphi-Referenz durchsuchenPos würde es nicht interessieren, solange man da nur nach Nicht-SurrogatePairs sucht, oder zumindestens nur komplette Surrogate-Paare sucht.

Luckie 18. Dez 2010 13:54

AW: Versteht hier jemand Unicode?
 
Und genau da hakt es. Bei diesen Zeichen, die nicht im BPM oder wie das heißt drin sind, Außerdem habe ich noch Verständnisprobleme was das BPM ist.

p80286 18. Dez 2010 14:10

AW: Versteht hier jemand Unicode?
 
Ich hab mich vor elend langer Zeit mal damit beschäftigt als die Norm noch ganz neu war.
Damals war es vereinfacht so, daß die ersten 8Bit den "Zeichensatz" angeben und die zweiten das eigentliche Zeichen identifizieren.
Das war ungefähr so aufgebaut, daß man als Basis das Standard ASCII hatte, und z.b. für die europ. Sonderzeichen eine eigene Tabelle dazu kam.
Da IBM und M$ es vorzogen die 256 Bytes zu vergewaltigen, hab ich damals die Beschäftigung damit wieder aufgegeben. In der Praxis gab es wohl auch zu viele Ungereimtheiten mit der Umsetzung von z.B. Minus, Gedankenstrich und Bindestrich.

Gruß
K-H

himitsu 18. Dez 2010 14:48

AW: Versteht hier jemand Unicode?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Jupp, die 16-Bit des UTF-16 wurden in mehrere Bereiche aufgeteilt.

Wobei die Basic Multilingual Plane (also die kodierten Werte von $0000 bis $FFFF) entsprechend aufgeteilt wurden.
Jeder Bereich enthält nur/vorwiegend bestimmte Zeichen (z.B. jeweils einer der vielen Sprachen).
Anhang 32818
Du kannst dir praktisch diese Grafik als das obere Byte ($xx00) vorstellen, wobei jedes Quadrat ein High-Byte darstellt.
(mehrfarbige Teilkästchen sind nochmals unterteilt)

Wenn man dieses jetzt zeichenweise interpretieren will, dann sind nur die zwei Surrogate-Bereiche wichtig, da davon jeweils ein High-Surrogate und ein Low-Surrogate zusammen ein Zeichen darstellen, welche im Bereich $00010000 bis $0010FFFF darstellen, die ja in die 16 Bit nicht reinpassen würden.
Außerdem wären die privaten Zeichen noch wichtig, also wo der Programmierer quasi selbst festlegen kann, was sie darstellen/enthalten sollen.

Aber wie gesagt, es kommt selten vor, daß diese Zeichen überhaupt mal vorkommen und meißtens ist es nicht schlimm, wenn man dieses Zusammengehören ignoriert und die beiden Surrogates jeweils als ein eigenes UCS2-Zeichen ansieht.



Einzig die Tatsache, daß UTF-32, UTF-16 und UTF-8 zwar alle gültigen Unicodezeichen darstellen können, aber leider intern nicht eine einheitliche Formatierung/Datenstruktur verwenden, finde ich für verwirrend.


UTF-32 ist also über den kompletten bereich direkt adressierbar.
- Datenwert $00000000..$0010FFFF = Zeichenwert
- unpraktisch ist, daß immer 4 Byte pro Zeichen belegt sind und davon auch maximal 0,0259% des gesamten möglichen Wertebereichs genutzt werden (drum nutzt es auch aum einer ... PS: den UCS4String kennt Delphi schon seit vielen Jahren, aber dieser ist leider nicht zuweisungskompatibel zu den anderen Strings :wall: )

UTF-16 ist großteils auch direkt adressierbar und der Rest ist in den Surrogates kodiert
- Datenwert $0000..$FFFF = Zeichenwert $0000..$FFFF
- die Surrogates = Zeichenwert $000010000..$0010FFFF

UTF-8 ist auch bekannt
- Datenwert $00..$7F = Zeichenwert $00..$7F
- Datenwerte $80..FF °1 = $000000080..$0010FFFF
°1 Bitweise auf ausreichend viele Bytes verteilt

Luckie 18. Dez 2010 17:24

AW: Versteht hier jemand Unicode?
 
Also im BMP Bereich sind alle zeichen kodiert, die am gebräuchlichsten sind. Dieser Bereich liegt in den 16 Bit. Dann gibt es noch den zweiten Bereich der mit zwei mal 16-Bit kodiert ist. Ist das soweit richtig? OK, nehmen wir mal an, ich hätte es richtig verstanden. Womit ich jetzt Probleme habe ist der Absatz, wo das mit den zwei mal 16-Bit erklärt wird:
Zitat:

Unicode-Zeichen außerhalb der BMP (d. h. U+10000 bis U+10FFFF) werden durch zwei 16-Bit-Wörter (engl. code units) dargestellt, die wie folgt gebildet werden:

Von der Nummer des Zeichens wird zunächst die Zahl 65536 (10000hex) abgezogen, wodurch eine 20-Bit-Zahl im Bereich von 00000hex bis FFFFFhex entsteht, die anschließend in zwei Blöcke zu je 10 Bit aufgeteilt und dem ersten Block die Bitfolge 110110, dem zweiten Block dagegen die Bitfolge 110111 vorangestellt wird. Das erste der beiden so entstandenen 16-Bit-Wörter bezeichnet man als High-Surrogate, das zweite als Low-Surrogate, und ihren Namen entsprechend enthält das High-Surrogate die 10 höherwertigen, das Low-Surrogate die 10 niederwertigen Bits des um 65536 verringerten ursprünglichen Zeichencodes. Der Codebereich von U+D800 bis U+DBFF (High-Surrogates) und der Bereich von U+DC00 bis U+DFFF (Low-Surrogates) ist speziell für solche UTF-16-Ersatzzeichen reserviert und enthält daher keine eigenständigen Zeichen.
Kann mir das noch mal jemand bitte erklären? Ich verstehe da nur Bahnhof.

BUG 18. Dez 2010 18:57

AW: Versteht hier jemand Unicode?
 
Also das Ganze funktioniert wie Escapen in Strings:

Ein UFT-16 Zeichen ist 16 Bit lang.
Also können darin nur die Zeichen von $0 bis $FFFF darin kodiert werden.

Da es aber viel mehr Unicodezeichen (also zusätzlich $10000 bis $10FFFF) gibt, müssen diese irgendwie codiert werden.
Wenn ein solches Zeichen codieren willst, ziehst du erstmal $10000 davon ab. Nun hast du das Zeichen in den Bereich $0 bis $FFFF codiert, also 20 Bit. (1)

Nun reserviert man sich innerhalb der 2^16 Zeichen einige, die man per Definition nicht als einzelne Zeichen betrachtet, sondern als "Surrogate"
Hier sind es alle, die (links mit Nullen aufgefüllt) binär codiert mit 110110 oder 110111 beginnen.

110110 und 110111 sind jeweils 6 Bit lang, du hast bei den Surrogates also jeweils 10 Bit "Nutzlast".

Dein 20 Bit Zeichen von (1) kannst du in 2 Blöcke je 10 Bit aufteilen.
Vor den ersten Block setzt du die Bitfolge 110110 und erhältst ein High-Surrogate. Vor den zweiten Block die Bitfolge 110111 und erhältst ein Low-Surrogate.

Nun hast du zwei 16-Bit-Folgen, die nach Definition einzeln keine Zeichen sind und zusammen ein Zeichen im Bereich $10000 bis $10FFFF codieren.

Damit kannst du nun also gefahrlos Zeichen im genannten Bereich in UTF-16 codieren.

Also aus "abc" mit a, c liegen im Bereich $0..$FFFF ohne die Surrogate Bereiche und b liegt im Bereich $100000..$10FFFF wird:
:arrow: "axyc" mit a, c liegen im Bereich $0..$FFFF ohne die Surrogate Bereiche sowie x ist ein High-Surrogate und y ist ein Low-Surrogate.

Luckie 18. Dez 2010 19:00

AW: Versteht hier jemand Unicode?
 
Puh, ist das kompliziert. ich werde es mir dann mal zu Gemüt führen.

himitsu 18. Dez 2010 19:10

AW: Versteht hier jemand Unicode?
 
Delphi-Quellcode:
if (TheChar in [$D800..$DBFF{High-Surrogates}, $DC00..$DFFF{Low-Surrogates}])
    or (TheChar > $10FFFF) or (weitere) then
  raise Exception.Create('ungültiges Zeichen')
else if TheChar > $FFFF then begin
  Temp := TheChar - $010000;
  TheWord[0] := (Temp shr 10) or $D800; // High-Surrogate
  TheWord[1] := (Temp and $03FF) or $DC00; // Low-Surrogate
end else
  TheWord[0] := TheChar;

BUG 18. Dez 2010 19:19

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von Luckie (Beitrag 1069284)
Puh, ist das kompliziert. ich werde es mir dann mal zu Gemüt führen.

Im Ernst: es ist weniger kompliziert als es aussieht.

Im Endeffekt ersetztet du jedes "zu große" Zeichen ($100000..$10FFFF) durch zwei andere, die im normalen Text nicht vorkommen (die Surrogates), also im nicht kodierten Text (UTF-32) als "Nichtzeichen" definiert und damit "verboten" sind.

himitsu 18. Dez 2010 19:29

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von BUG (Beitrag 1069289)
Im Ernst: es ist weniger kompliziert als es aussieht.

...

Ist also fast soein Verfahren, wie das URLEncode auch.
http://php.net/manual/de/function.urlencode.php

Assarbad 18. Dez 2010 21:43

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von himitsu (Beitrag 1069256)
UTF-32 ist also über den kompletten bereich direkt adressierbar.
- Datenwert $00000000..$0010FFFF = Zeichenwert
- unpraktisch ist, daß immer 4 Byte pro Zeichen belegt sind und davon auch maximal 0,0259% des gesamten möglichen Wertebereichs genutzt werden (drum nutzt es auch aum einer ... PS: den UCS4String kennt Delphi schon seit vielen Jahren, aber dieser ist leider nicht zuweisungskompatibel zu den anderen Strings :wall: )

Dein Browser kann kein Javascript? :shock:

Der ECMAScript-Standard auf dem Javascript aufbaut benutzt meines Wissens nach intern UTF-32.

Zitat:

Zitat von himitsu (Beitrag 1069256)
UTF-8 ist auch bekannt
- Datenwert $00..$7F = Zeichenwert $00..$7F
- Datenwerte $80..FF °1 = $000000080..$0010FFFF
°1 Bitweise auf ausreichend viele Bytes verteilt

Die einfachste Kodierung überhaupt, da auf die Reihenfolge der Bytes nicht geachtet werden muß. Das macht man sich vielleicht sonst nicht so klar, aber das ist ein riesiger Vorteil.

Luckie 24. Dez 2010 01:08

AW: Versteht hier jemand Unicode?
 
Also, ich habe innerhalb des 16-Bit Bereichs, dem BMP, wo die Zeichen mit 16-Bit kodiert sind einen Bereich, der reserviert ist. Innerhalb dieses Bereiches werden die Zeichen mit zwei mal 16-Bit kodiert. Wobei bei diesen beiden 16-Bit die oberen sechs Bits zur Kennzeichnung dienen, dass es sich um Zeichen in diesen Reservierten Bereich handelt.

Stimmt die Erklärung des Prinzips soweit? Wie die die Kodierung im Einzelnen zu Stande kommt, ist erst mal nicht so wichtig. Ich will nur wissen, ob ich das Prinzip verstanden habe.

BUG 24. Dez 2010 01:21

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von Luckie (Beitrag 1070254)
Also, ich habe innerhalb des 16-Bit Bereichs, dem BMP, wo die Zeichen mit 16-Bit kodiert sind einen Bereich, der reserviert ist. Innerhalb dieses Bereiches werden die Zeichen mit zwei mal 16-Bit kodiert. Wobei bei diesen beiden 16-Bit die oberen sechs Bits zur Kennzeichnung dienen, dass es sich um Zeichen in diesen Reservierten Bereich handelt.

Mit je zwei "Zeichen" aus diesem Bereich werden die Zeichen kodiert, die sonst nicht in die 16 Bit passen würden (also nicht in der BMP liegen). Ich nehme an, das meinst du?

Zitat:

Zitat von Luckie (Beitrag 1070254)
Stimmt die Erklärung des Prinzips soweit?

Sieht fast so aus :wink:

Luckie 24. Dez 2010 01:24

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von BUG (Beitrag 1070255)
Mit je zwei "Zeichen" aus diesem Bereich werden die Zeichen kodiert, die sonst nicht in die 16 Bit passen würden (also nicht in der BMP liegen). Ich nehme an, das meinst du?

Nein, aber jetzt verstehe ich auch das Beispiel mit abc und axyc. b liegt nicht in der BMP, deswegen wird es mit x und y als Ersatz kodiert. Und x und y liegen in diesem reservierten Bereich - oder?

BUG 24. Dez 2010 01:35

AW: Versteht hier jemand Unicode?
 
Ja.

x wäre dann das High-Surrogate und y das Low-Surrogate.

Luckie 24. Dez 2010 01:41

AW: Versteht hier jemand Unicode?
 
Ich habe es jetzt so formuliert:
Zitat:

UTF-16 ist von den drei Unicode Kodierungen die komplizierteste. Bei UTF-16 kann man zwei Bereiche unterscheiden. Der erste Bereich ist der 16-Bit Bereich, in dem die Zeichen direkt kodiert sind. Dieser beinhaltet die am häufigsten genutzen Zeichen. Innerhalb dieses Bereiches gibt es einen zweiten, reservierten Bereich. In diesem reservierten Bereich werden einzelne Zeichen mit mit zwei mal 16-Bit, also zwei Ersatzzeichen definiert. Nehmen wir die Zeichenfolge abc, wobei bei b nicht im direkt kodierten 16-Bit Bereich liegt. Diese Zeichenfolge wird nun mit axyc kodiert, wobei xy zwei Zeichen innerhalb dieses reservierten Bereiches sind.
So, ich habe meinen Unicode Artikel fertiggestellt: UTF für die Westentasche. Wenn ihr keine Korrekturen mehr habt, dann veröffentliche ich ihn auch hier als Einführungstutorial.

Assarbad 24. Dez 2010 20:20

AW: Versteht hier jemand Unicode?
 
Zitat:

Zitat von Luckie (Beitrag 1070258)
So, ich habe meinen Unicode Artikel fertiggestellt: UTF für die Westentasche. Wenn ihr keine Korrekturen mehr habt, dann veröffentliche ich ihn auch hier als Einführungstutorial.

"Wikipeia"? Ganz unten in deinem Artikel ;)

Hyroglyphen schreibt man mit "ie": Hieroglyphen.

"auf acht Bit erweiter" -> "auf acht Bit erweitert"

Der zweite Absatz klingt als sei ASCII erweitert worden, was aber nicht stimmt. ASCII waren und sind exakt 7bit.

Außerdem wäre es lesbarer wenn die Zahlen mit Ziffern geschrieben würden, zumindest bei Computerthemen.

"128 bis 256" -> "128 bis 255"

"Dies Kodierung wurde" -> "Diese Kodierung wurde"

Statt Byte würde ich die Bezeichnung Oktett benutzen, oder eine Definition für Byte geben. Denn ein Byte ist nicht immer 8bit. Und für diese Diskussion ist es relevant.

"Fangt das Byte" -> "Fängt das Byte"

"immer mit einer null" -> "immer mit einer Null"

"einzelne Zeichen mit mit zwei mal" -> "einzelne Zeichen mit zwei mal"

Bei dem zitierten Text solltest du den Permalink (zur aktuellen Version) angeben.

Habe sicher noch was übersehen.

Zitat:

Ursprünglich wurden Zeichen im sogenannten ASCII (American Standard Code for Information Interchange) Format kodiert.
Greift zu kurz, da hier genau das passiert, was schon immer passierte: Konzentration auf den Bedarf des westlichen Kulturkreises unter Ausschluß des nahen oder fernen Ostens, Afrikas usw. Wie westlich orientiert es ist, sieht man an der Tatsache, daß in der "westlichen Codepage" ein einziges Zeichen für Türkisch fehlte, während Isländisch - eine Sprache von damals vielleicht 250.000 Sprechern - voll vertreten ist/war.

Übrigens kann ich nicht zustimmen, daß UTF-16 die komplizierteste Kodierung ist. Worauf stützt du diese Aussage?

Eine sorgfältigere Begriffswahl wäre angesagt:
* "code unit" (1 Oktett, 2 Oktette, 4 Oktette)
* "code point"
* "glyph"
* "grapheme"
* "character"

Alles diese Begriffe stehen bei der Diskussion von Unicode in einer Beziehung, aber wenn man sie korrekt einsetzt und jeder im Bilde ist, kann man Verwirrung leichter vermeiden als wenn man bspw. "character" (Zeichen) für mehrere dieser Begriffe verwendet.


Frohes Fest.

Luckie 25. Dez 2010 00:31

AW: Versteht hier jemand Unicode?
 
Danke fürs Lesen, werde ich die Tage überarbeiten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz