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

Шрифт
Интервал

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

1.1.3. Base64

Алгоритм кодирования 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 H15 P23 X31 f39 n47 v55 363 /

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


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Программное обеспечение встроенных систем. Общие требования к разработке и документированию

Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.