Codierung und Decodierung
Information und Daten
Auf der Bitübertragungsschicht spielt es keine Rolle welche Informationen übertragen werden. Wichtig ist nur, dass die geschickten Bytes richtig beim Empfänger ankommen. Wie dieser die Bytes zu interpretieren hat, ist auf dieser Schicht nicht definiert. Um bei unseren Experimenten dennoch nicht nur 0-1-Folgen anzuzeigen, können wir die übertragenen Daten als Text interpretieren, was im Prizip aber willkürlich festgelegt ist. Wie man Texte in Bitfolgen umwandelt, soll im Folgenden beschrieben werden.
Zeichencodierung der geläufigsten Zeichen
Um die häufigsten Zeichen im deutschsprachigen Raum (genauer: Zeichen aus ISO 8859-1) zu codieren, reicht ein einzelnes Byte. (Möchtest Du beliebige Zeichen codieren, dann kannst Du wie weiter unten beschrieben vorgehen.)
Codierung
Wie man Zeichen binär codieren kann, kannst Du dem folgenden Dialog entnehmen:
>>> text = 'Hallöchen'
>>> for zeichen in text:
print(ord(zeichen))
72
97
108
108
246
99
104
101
110
>>> bin(72)
'0b1001000'
>>> bin(72)[2:]
'1001000'
>>> bin(72)[2:].zfill(8)
'01001000'
Aufgabe 1 - Zeichen codieren
Probiere das selbst einmal aus und erkläre was in jeder Zeile passiert.
Decodierung
Der folgende Dialog demonstriert wie man von einer Binärcodierung wieder zum Zeichen kommt:
>>> codierung = '01001000'
>>> int(codierung) # So geht's nicht! Warum?
1001000
>>> int(codierung, 2)
72
>>> chr(72)
'H'
Aufgabe 2 - Zeichen decodieren
Probiere das selbst einmal aus und erkläre was in jeder Zeile passiert.
Zeichencodierung beliebiger Zeichen
Um (fast) beliebige Zeichen zu codieren, kannst Du z.B. die Codierung nach UTF-8 vornehmen. Wie dies funktioniert, ist im Folgenden beschrieben. Beachte aber, dass sich bei der Übertragung der Daten dadurch weitere Herausforderungen ergeben, da Zeichen dann unterschiedlich lange Codierungen besitzen.
Die folgenden Experimente benutzen den Python-Datentyp bytes
zur Byte-Darstellung
von Zeichen.
Mit Hilfe der gleichnamigen Umwandlungsoperation bytes
kann man eine Zeichenkette in
eine Bytefolge umwandeln. Dabei muss man die zu benutzende Codierung angeben.
Mit der Umwandlungsoperation str
kann man eine Bytefolge wieder in eine
Zeichenkette umwandeln. Auch hier muss man die zu benutzende Codierung angeben.
Python-Dialog 1:
>>> text = 'hallo!'
>>> bytefolge = bytes(text, 'iso8859-1')
>>> bytefolge
b'hallo!'
>>> str(bytefolge, 'iso8859-1')
'hallo!'
>>> text = 'äußerst böse'
>>> bytefolge = bytes(text, 'utf8')
>>> bytefolge
b'\xc3\xa4u\xc3\x9ferst b\xc3\xb6se'
>>> str(bytefolge, 'utf8')
'äußerst böse'
Aufgabe 3
Analysiere den gezeigten Dialog. Teste selbst weitere Dialoge dieser Art. Kannst du die Zusammenhänge erklären?
Python-Dialog 2:
>>> bytefolge = b'b\xc3\xb6se'
>>> for byte in bytefolge:
print(byte)
98
195
182
115
101
>>> for byte in bytefolge:
print(hex(byte))
0x62
0xc3
0xb6
0x73
0x65
>>> for byte in bytefolge:
print(bin(byte))
0b1100010
0b11000011
0b10110110
0b1110011
0b1100101
>>> for byte in bytefolge:
print(bin(byte)[2:].zfill(8))
01100010
11000011
10110110
01110011
01100101
Aufgabe 4
Dialog 2 zeigt, wie man die Binärdarstellung der Bytes einer Bytefolge erzeugt. Probiere es selbst aus. Kannst du die jeweils erzeugten Ausgaben deuten?
Python-Dialog 3:
>>> text = 'böse'
>>> bytefolge = bytes(text, 'utf8')
>>> listeBitfolgen = []
>>> for byte in bytefolge:
bitfolge = bin(byte)[2:].zfill(8)
listeBitfolgen = listeBitfolgen + [bitfolge]
>>> listeBitfolgen
['01100010', '11000011', '10110110', '01110011', '01100101']
Python-Dialog 4:
>>> listeBitfolgen = ['01100010', '11000011', '10110110', '01110011', '01100101']
>>> bytefolge = b''
>>> for bitfolge in listeBitfolgen:
byte = int(bitfolge, 2)
bytefolge = bytefolge + bytes([byte])
>>> bytefolge
b'b\xc3\xb6se'
>>> text = str(bytefolge, 'utf8')
>>> text
'böse'
Aufgabe 5
Teste und analysiere die Dialoge 3 und 4. Jetzt sollte klar sein, wie man mit Python Zeichenketten Schritt für Schritt in Bitfolgen umwandelt und umgekehrt.