7-Bit/8-Bit-Konvertierung
Manchmal ist es aus historischen oder technischen Gründen notwendig, nur Teile eines Bytes für eine Botschaft zu verwenden. Beispielsweise dürfen klassische E-Mails nur aus 7-Bit-ASCII-Zeichen bestehen. Möchte man andere Daten über das E-Mail-Format austauschen, wird es nötig, diese zuvor in ein mit E-Mails kompatibles Format umzuwandeln.
Ähnliches trifft auch auf die kürzlich vorgestellte Verschlüsselungsmethode für Lokalteile von E-Mail-Adressen zu. Während ein Byte mit seinen acht Bits grundsätzlich 256 verschiedene Zustände annehmen kann, erwartet jene Methode Eingaben nur im Bereich 0–127, es können also nur sieben Bits jedes Bytes für die Nachricht genutzt werden. Wandelt man allerdings 8-Bit-kodierte Daten zuvor in eine 7-Bit-kodierte Form um, lassen auch sie sich mit einer so beschränkten Methode verarbeiten.
Eine von zahlreichen Möglichkeiten einer solchen 8-Bit-7-Bit-Konvertierung wird auf dieser Seite dargestellt und in PHP exemplarisch realisiert.
Beispielhafte Darstellung
In der folgenden Tabelle wird eine Botschaft „süßer Käse“ in einer 8-Bit-Kodierung ISO 8859-1 dargestellt. Die farbliche Unterlegung besitzt keine inhaltliche Bedeutung, sondern dient nur der Veranschaulichung der Umwandlung von acht zu sieben Bits pro Byte und umgekehrt.
Zeichen | 8 Bits je Byte | 7 Bits je Byte |
---|---|---|
s ü ß e r K ä s e |
01110011 11111100 11011111 01100101 01110010 00100000 01001011 11100100 01110011 01100101 |
.0111001 .1111111 .1101100 .0110111 .0110101 .0010010 .0100000 .1001011 .1110010 .0111000 .0110011 .....101 |
Fürs Umwandeln von einer 8- zu einer 7-Bit-kodierten Nachricht wird jeweils ein Block aus sieben Bytes à acht Bits in zwei Dreiecke, blau und gelb, unterteilt. Die 7-Bit-kodierte Nachricht ergibt sich, wenn das blaue Dreieck einen Schritt nach rechts und das gelbe Dreieck einen Schritt nach unten verschoben wird.
Die Umwandlung einer 7-Bit-kodierten in eine 8-Bit-kodierte Nachricht funktioniert dementsprechend so: Jeweils ein Block aus acht Bytes à sieben (genutzten) Bits wird in zwei Dreiecke unterteilt. Das blaue Dreieck wird einen Schritt nach links, das gelbe einen Schritt nach oben verschoben.
PHP-Quelltext
<?php
/* prlbr_78
* is a class that converts between 7- and 8-bit encoded strings
*/
class prlbr_78 {
private static $up = array (1, 3, 7, 15, 31, 63, 127);
private static $down = array (254, 252, 248, 240, 224, 192, 128, 0);
/* to7
* converts an 8-bit encoded $input string into a 7-bit encoded string
*/
public static function to7 ($input) {
// the empty string is encoded as empty string
if ($input === ''):
return '';
endif;
// initialize the output string and carry
$output = '';
$carry = 0;
for ($i = 0, $length = strlen ($input); $i < $length; $i++):
// calculate the round number modulo 7
$r = $i % 7;
// add the carry as a character to the output every seventh round
if (($r === 0) && ($i !== 0)):
$output .= chr ($carry);
$carry = 0;
endif;
// represent an input byte as 8-bit integer
$integer = ord ($input[$i]);
// add a 7-bit output byte created from the r-bit carry and the
// lower 7 - r bits from the 8-bit input integer
$output .= chr ($carry | (($integer & self::$down[$r]) >> 1));
// save the other r + 1 bits of the 8-bit integer as new carry
$carry = $integer & self::$up[$r];
endfor;
// add the remaining carry as a character to the output
return $output . chr ($carry);
} // public static function to7
/* to8
* converts a 7-bit encoded $input string into an 8-bit encoded string
*/
public static function to8 ($input) {
// initialize the output string and carry
$output = '';
$carry = 0;
for ($i = 0, $length = strlen ($input); $i < $length; $i++):
// calculate the round number modulo 8
$r = $i % 8;
// represent an input byte as a 7-bit integer
$integer = ord ($input[$i]);
// add an 8-bit output byte created from the 8 - r bits carry
// and r bits from the 7-bit integer
if ($r !== 0):
$output .= chr ($carry | ($integer & self::$up[$r - 1]));
endif;
// save the other 7 - r bits of the 7-bit integer as new carry
$carry = ($integer << 1) & self::$down[$r];
endfor;
return $output;
} // public static function to8
} // class prlbr_78
// end