Da auch dieseswelches Thema in letzter Zeit bedenklich häufig auftaucht, wollte ich doch unbedingt mal etwas Senf dazugeben.
Irgendwie scheint bei vielen Leuten Verwirrung zu bestehen, wie sich die Information von deren Repräsentation unterscheidet. Da will man "Hex an den
COM-Port schicken" oder "
ANSI und
ASCII unterscheiden" ... traurig, welche Grundlagen da zu fehlen scheinen.
Das Byte
Das Byte ist die kleinste nichtteilbare Dateneinheit und wird üblicherweise auf 32bit-PCs als ein Block aus 8 Bits angesehen. Diese 8 Bits kann man zwar einzeln manipulieren, man kann jedoch das Byte nicht noch einmal so zerlegen, daß daraus 8 einzelne Bit werden. Byte ist auch ein Typ in Delphi und entspricht dort direkt der oben beschriebenen Entität. Es handelt sich um eine 8 Bit breite vorzeichenlose Zahl.
Das bringt uns dahin, daß wir wissen, daß ein Bit entweder den Wert 0 oder 1 annehmen kann und dementsprechend bei 8 Bit ganze 2^8 (zwei hoch 8) oder 256 verschiedene Zahlenwerte möglich sind. Diese Zahlenwerte kann man nun binär darstellen (
Repräsentation!):
Code:
0000 0000
0000 0001
0000 0010
0000 0011
0000 0100
.
.
.
1111 1111
Die Trennung in zwei Viererblöcke von Binärstellen erfolgte mit Absicht. Vier Binärstellen nennt man Nibble (oder Halb-Byte). Obwohl ein Nibble natürlich wiederum kleiner als ein Byte ist und deshalb nicht einzeln stehen kann, spielt es eine wesentliche Rolle bei der Repräsentation der Zahlen in Hexadezimalform:
Code:
0 0
0 1
0 2
0 3
0 4
.
.
.
F F
Auch hier habe ich die Nibble einmal getrennt, so daß man sehen kann, daß ein Nibble einer Stelle in der Hexadezimaldarstellung entspricht. So kann man sich die Konvertierung von der Binär- in die Hexadezimaldarstellung erleichtern, indem man sich eine kleine "Tabelle" erstellt und die Binärwerte den Hexadezimalwerten gegenüberstellt:
Code:
0000b = 0h = 0
0001b = 1h = 1
0010b = 2h = 2
0011b = 3h = 3
0100b = 4h = 4
0101b = 5h = 5
0110b = 6h = 6
0111b = 7h = 7
1000b = 8h = 8
1001b = 9h = 9
1010b = Ah = 10
1011b = Bh = 11
1100b = Ch = 12
1101b = Dh = 13
1110b = Eh = 14
1111b = Fh = 15
(b steht für binär, h für hexadezimal und ohne Suffix ist dezimal)
So kann man Binärzahlen also von rechts nach links in Viererblöcken nach hexadezimal konvertieren und füllt fehlende Stellen (zum Viererblock) nach links mit Nullen auf.
Hier haben wir schon das erste Beispiel für Repräsentation versus Information. Obwohl man offensichtlich etwas anderes sieht wenn man einmal 15 und einmal Fh schreibt, ist der dahinterstehende Wert der gleiche.
Ab nun verwende ich für die Hexadezimalform das $ und für die Dezimalform keinen Präfix, entsprechend der Delphi-Syntax.
Das Zeichen
Zeichen sind eine Darstellungsform. Die Tatsache, daß wir üblicherweise das Zeichen $41 (auch #$41) als 'A' sehen, sagt nichts darüber aus, ob dieses Zeichen in einer anderen Kodierung nicht ganz anders aussehen könnte als der lateinische Buchstabe A. Nun gibt es aber zum Glück die allgemein anerkannte Kodierung
ASCII, die die ersten 128 Zeichen (Werte 0 bis 127) standardisiert, so daß diese im Grunde überall gleich dargestellt werden. Jedoch schon bei
EASCII, jenem Standard der noch die Zeichenwerte von 128 bis 255 dem
ASCII-Standard hinzufügt, gibt es verschiedene Kodierungen (westlich, kyrillisch, arabisch ...). Dort wird beispielsweise der Wert $9D für den Buchstaben Ю (russisches großes Yu) für kyrillisch verwendet, wohingegen in westeuropäischer Kodierung ein Ø (verwendet zB. im Dänischen, wie Ö) dargestellt wird. Ein Wert kann also auch noch als Zeichen unterschiedliche Darstellungsformen haben.
Aber jetzt kommt der Hammer. Kluge Leute haben sich gedacht, daß für alle Zeichen die es auf der Welt so gibt, die Byte-Werte niemals ausreichen können. Schon zwischen der US-Kodierung und der westeuropäischen Kodierung von
EASCII gibt es ja Unterschiede. Man mußte sich also etwas anderes einfallen lassen. Und das war
Unicode.
Unicode gibt es inzwischen in verschiedenen Formen, die bei Windows NT und damit für uns relevanteste Form ist UCS-2. Für jedes Zeichen ist ein 16bit-Wert reserviert (genaugenommen stimmt das nicht, aber das ginge jetzt zu sehr ins Detail). Somit kann jede Darstellung eines Zeichens eindeutig einem Wert zugeordnet werden. Beispielsweise ist das russische Yu von vorhin jetzt mit dem Wert $042E (dezimal 1070)vertreten (also offenbar ein Wert größer als 255).
Natürlich muß ein Programm genau diese Kodierung,
Unicode, kennen um sie korrekt darstellen zu können. Würde es die Zeichen als 8bit-Zeichenwerte interpretieren, käme eine komplett andere Darstellung heraus.
Und dennoch ist jedes dieser filigranen und weniger filigranen Zeichen für den PC nur eine Zahl und wird auch so abgespeichert. Nur weil wir einen Hexeditor haben, können wir diese Zeichenwerte in Hexadezimaldarstellung anzeigen lassen, nur weil wir Notepad haben, können wir die russischen
Unicode-Texte auch lesen. So ist es immer dem Programm überlassen, wie es eine bestimmte Zahl darstellt, ob nun als Zeichen, als Dezimalzahl, als Hexadezimalzahl oder komplett anders. Zahl bleibt Zahl, nur die Darstellung ändert sich.
Es gibt viele verschiedene Kodierungsformen, aber wir dürfen uns nicht verleiten lassen, von der Kodierung auf die Darstellung zu schließen. So nimmt es doch jeder von uns als gegeben hin, daß wir Delphi-Quelltext schreiben und dieser nach dem Kompilieren vom Prozessor verstanden wird. Auch hier ist der Delphi-Quelltext nur eine menschenfreundliche Darstellung dessen was der Compiler später daraus macht ...
Ich hoffe dieser kurze Beitrag trägt zum Verständnis des Problems bei ...