Интернет-решения от доктора Боба

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 логического типа для определения типа кодирования.


Содержание раздела