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