XXEncode и XXDecode
UUкодирование было наиболее популярным форматом 64 битного кодирования. Ограничение состояло в том, что набор символов не мог транслироваться между наборами ASCII и EBCDIC (IBM мейнфреймы). XXencode очень похож на UUEncode, просто используется другой набор символов, что более удобно между различными типами систем, например как указано выше между EBCDIC и ASCII.
Набор символов XXEncode | |||||||||||||||||
0 + | 8 6 | 16 E | 24 M |
| 32 U | 40 c | 48 k | 56 s | |||||||||
1 - | 9 7 | 17 F | 25 N | 33 V | 41 d | 49 l | 57 t | ||||||||||
2 0 | 10 8 | 18 G | 26 O | 34 W | 42 e | 50 m | 58 u | ||||||||||
3 1 | 11 9 | 19 H | 27 P | 35 X | 43 f | 51 n | 59 v | ||||||||||
4 2 | 12 A | 20 I | 28 Q | 36 Y | 44 g | 52 o | 60 w | ||||||||||
5 3 | 13 B | 21 J | 29 R | 37 Z | 45 h | 53 p | 61 x | ||||||||||
6 4 | 14 C | 22 K | 30 S | 38 a | 46 i | 54 q | 62 y | ||||||||||
7 5 | 15 D | 23 L | 31 T | 39 b | 47 j | 55 r | 63 z | ||||||||||
Заметим что если для UUEncode используется подмножество набора символов ASCII (32..96), то для XXEncode это не так.
Для преобразования процедур Triplet2Kwartet и Kwartet2Triplet для поддержки мы вводим дополнительный массив из 64 символов.
Нам также необходимо модифицировать процедуры Triplet2Kwartet и Kwartet2Triplet следующим образом.
const
XX: Array[0..63] of Char =
'+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
procedure
Triplet2Kwartet(const Triplet: TTriplet;
var
Kwartet: TKwartet);
var
i: Integer;
begin
Kwartet[0] := (Triplet[0] SHR
2);
Kwartet[1] := ((Triplet[0] SHL
4) AND $30) +
((Triplet[1] SHR
4) AND $0F);
Kwartet[2] := ((Triplet[1] SHL
2) AND $3C) +
((Triplet[2] SHR
6) AND $03);
Kwartet[3] := (Triplet[2] AND
$3F);
for i:=0 to 3 do
if Kwartet[i] = 0 then
Kwartet[i] := $40 + Ord(SP)
else
Inc(Kwartet[i],Ord(SP));
if XXCode then
for i:=0 to 3 do
Kwartet[i] := Ord(XX[(Kwartet[i] - Ord(SP)) mod $40])
end {Triplet2Kwartet};
Последние несколько строк новые для процедуры Triplet2Kwartet и мы используем набор символов XXencode для возврата правильно закодированных символов. Помните, что UUEncode возвращает индекс кодированного символа, после чего мы к нему добавляем код #32, так что если XXencode используется после преобразования в UUEncode, то мы должны вычесть 32 и использовать результат как индекс в таблицу символов XXencode.
То же самое относится и к процедуре Kwartet2Triplet, где мы должны преобразовать XXencode символы перед использованием алгоритма UUdecode (заметим, что мы теперь не передаем Kwartet как const).
procedure Kwartet2Triplet(Kwartet: TKwartet;
var Triplet: TTriplet);
var
i: Integer;
begin
if
XXCode then
begin
for
i:=0 to 3 do
begin
case
Chr(Kwartet[i]) of
'+': Kwartet[i] := 0 + Ord(SP);
'-': Kwartet[i] := 1 + Ord(SP);
'0'..'9': Kwartet[i] := 2 + Kwartet[i]
- Ord('0') + Ord(SP);
'A'..'Z': Kwartet[i] := 12 + Kwartet[i]
- Ord('A') + Ord(SP);
'a'..'z': Kwartet[i] := 38 + Kwartet[i]
- Ord('a') + Ord(SP)
end
end
end;
Triplet[0] := ((Kwartet[0] - Ord(SP)) SHL 2) +
(((Kwartet[1] - Ord(SP)) AND $30) SHR
4);
Triplet[1] := (((Kwartet[1] - Ord(SP)) AND $0F) SHL
4) +
(((Kwartet[2] - Ord(SP)) AND $3C) SHR
2);
Triplet[2] := (((Kwartet[2] - Ord(SP)) AND $03) SHL
6) +
((Kwartet[3] - Ord(SP)) AND $3F)
end
{Kwartet2Triplet};
Заметим, что в новой версии этих процедур используется глобальная переменная XXCode логического типа для определения типа кодирования.