Выбрать главу

Подобно набору символов 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};

Заметим, что в новой версии появилась новая глобальная переменная, которая используется для определения формата кодирования.

1.1.4. MIME

MIME означает Multipurpose Internet Mail Extensions (Расширение форматов Интернет почты), в котором международным стандартом является кодирование Base64. Данное расширение было разработано для многоязычной поддержки и преобразования символов между системами (такими как IBM мейнфреймы, системы на базе UNIX, Macintosh и IBM PC).

MIME алгоритм кодирования базируется на RFC1341 как MIME Base64. Подобно UUencode, назначение MIME кодировать двоичные файлы так, что бы они смогли пройти через различные почтовые системы, и MIME использует для этого алгоритм кодирования Base64, плюс набор специальных ключевых слов и опций, которые используются для более детализированной информации о содержимом MIME.

1.1.5. TBUUCode компонент

Определение интерфейса компонента TUUCode, базируется на ранее приведенных и объясненных процедур Triplet2Kwartet и Kwartet2Triplet, заметим, что ниже приведенный код использует условное компилирование в зависимости от версий Delphi и C++Builder.

unit UUCode;

 interface

 uses

 {$IFDEF WIN32}

   Windows,

 {$ELSE}

   WinTypes, WinProcs,

 {$ENDIF}

   SysUtils, Messages, Classes, Graphics, Controls, Forms;

 {$IFNDEF WIN32}

 type

   ShortString = String;

 {$ENDIF}

 type

   EUUCode = class(Exception);

   TAlgorithm = (filecopy, uuencode, uudecode, xxencode, xxdecode, Base64encode, Base64decode);

   TUnixCRLF = (CRLF, LF);

   TProgressEvent = procedure(Percent:Word) of Object;

   TBUUCode = class(TComponent)

   public

   { Public class declarations (override) }

     constructor Create(AOwner: TComponent); override;