(* +------------------------------------------------------------------------------+ | МОДУЛЬ | | для base64 кодирования и декодирования | | ************************************************* | | | | Суть base64-кодирования заключается в конвертации байтов в текст по принципу | | 3 к 4. Т.е. три 8-ми битных байта (размер 0-255) конвертируются в четыре | | символа, код которых занимает 6 байтов (размер 0-63). Алфавит base64 | | состоит из 64 символов: | | ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ | | где символ A имеет код 0, а символ / имеет код 63. | | | | Пример. Имеем три числа 103, 193, 58. Их надо закодировать в base64 формат. | | 1. Берем первые 6 байтов первого числа (103) и записываем их в перый base64 | | 6-ти битный код. Получаем число 25. | | 2. Берем оставшиеся 2 байта первого числа (103) и первые 4 байта второго | | числа (193). Записываем их во второй base64 6-ти битный код. Получаем | | число 60. | | 3. Берем оставшиеся 4 байта второго числа (193) и 2 первые байта третьего | | числа (58). Записываем их в третий base64 6-ти битный код. Получаем | | число 4. | | 4. Берем последние 6 байтов третьего числа (58) и записываем их в четвертый | | base64 6-ти битный код. Получаем число 58. | | 5. Обращаемся к base64 алфавиту: | | номер позиции символа в стринге алфавита = base64-код + 1 | | | | десятичное число: 103 193 58 | | двоичное число: 01100111 11000001 00111010 | | двоичный 6-ти бит. base64-код: 011001 111100 000100 111010 | | десятичный вид base64-кода: 25 60 4 58 | | base64 символ: Z 8 E 6 | | | | Что делать, если при чтении последних байтов из файла число байт составляет | | менее трех? В этом случае надо поступать так: | | 1. Если считывает один байт, то в конец base64 квартета дописывается два | | символа = (равно): | | Ew== | | 2. Если считывается два байт, то дописывается один символ равно: | | Ew6= | | 3. Если считываются три символа, то ничего не дописывается: | | Ew6y | | | | Base64 имеет граничение: | | - длина base64 кодированной строки должна составлять не более 72 символов. | | | | Как использовать модуль. | | | |1. Подключаем модуль Base64Unit к своему проекту | | | |2. Кодирование | |2.1 Заполняем переменную типа TBase64.ByteArr нужными байтами и указываем | | в TBase64.ByteCount количество байт к кодированию | |2.2 Вызываем функцию CodeBase64(TBase64), в результате получаем String | | закодированный в формате base64 | |2.3 При обработке кодированного base64 стринга не забываем, что его строка | | должна составлять 72 символа. | | | |3. Декодирование | |3.1 Вызываем функцию DecodeBase64, в качестве аргумента передаем четыре | | символа base64 кодированной строки, в результате получаем декодирован- | | ные байты в массиве TBase64.ByteArr и их количество в TBase64.ByteCount | | | | (c) 2002 Терехов А.В. | | http://www.inta.portal.ru/dark/index.html | | mailto:dark@online.ru | | | | | *************************************************************** | | Вы можете использовать этот модуль по своему усмотрению, при условии | | сохранения выше приведенного описания. | | | +------------------------------------------------------------------------------+ *) unit Base64Unit; interface Const //base64 алфавит base64ABC='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; Type TBase64 = Record //структура для работы с base64 ByteArr : Array [0..2] Of Byte;//массив из трех байтов ByteCount:Byte; //количество считанных байт End; //кодируем base64 Function CodeBase64(Base64:TBase64):String; //декодируем base64 Function DecodeBase64(StringValue:String):TBase64; implementation //==============================CodeBase64====================================== //кодируем base64 Function CodeBase64(Base64:TBase64):String; Var N,M:Byte; Dest, //результат - 6-ти битное число с base64-кодом Sour:Byte; //исходное 8-ми битное число NextNum:Byte;// флаг-счетчик для начала работы со следующим 6-ти битным числом Temp:Byte; //вспомогательная переменная используется для проверки старшего байта //8-ми битного исходного числа Begin {CodeBase64} //обнуляем результат Result:=''; //инициализируем флаг - "следущее 6-ти битное число" NextNum:=1; //обнуляем 6-ти битный результат Dest:=0; //будем работать с массивом из трех байтов For N:=0 To 2 Do Begin {For N} //берем очередной байт-источник Sour:=Base64.ByteArr[N]; //пройдемся по всем 8-ми битам байта источника For M:=0 To 7 Do Begin {For M} //будем работать не с самим байтом источником, а с его копией Temp:=Sour; //делаем побитный сдвиг влево для байта-источника и байта-приемника Temp:=Temp SHL M; Dest:=Dest SHL 1; //если старший бит байта-источника равен 1 If (Temp And 128) = 128 Then //в байте приемнике устанавливаем младший бит в 1 Dest:=Dest Or 1; //увеличиваем счетчик перехода к следующему байту-приемнику Inc(NextNum); //если обработаны все 6 битов числа-приемника If NextNum > 6 Then Begin {If NextNum} //заполняем результат функции, добавляя к нему символ из строки base64-алфавита //с кодом на 1 больше, чем Dest (base64 коды начинаются с 0, а код первого //символа строки base64-алфавита 1). Result:=Result+base64ABC[Dest+1]; //обнуляем счетчик обработанных бит 6-ти битного числа-премника NextNum:=1; //обнуляем число-приемник Dest:=0; End; {If NextNum} End; {For M} End;{For N} //добавим конечный знак = (равно) //один знак, если обрабатываются два байта и два знака, если обрабатывается 1 байт //не забываем, что кодированный стринг состоит из 4 символов If Base64.ByteCount < 3 Then For N:=0 To (2 - Base64.ByteCount) Do Result[4-N]:='='; End; {CodeBase64} //==============================CodeBase64====================================== //****************************************************************************** //================================DecodeBase64================================== //декодируем base64 Function DecodeBase64(StringValue:String):TBase64; Var M,N:Integer; Dest, //6-ти битное число-источник Sour:Byte; //8-ми битный байт-приемник NextNum:Byte; //флаг-счетчик перехода к следующему 8-ми битному байту CurPos:Byte; //текущая позиция в массиве TBase64.ByteArr обрабатываемого //8-ми битного байта-приемника Begin {DecodeBase64} //обнуляем значния всех переменных CurPos:=0; Dest:=0; NextNum:=1; FillChar(Result,SizeOf(Result),#0); //будем обрабатывать каждый из 4 символов base64-кодированной строки For N:=1 To 4 Do Begin {For N} //будем обрабатывать каждый бит 6-ти битного числа-источника For M:=0 To 5 Do Begin {For M} //если обрабатывается символ "отсутствие байтов", обнуляем число-приемник If StringValue[N]='=' Then Sour:=0 Else //иначе в число источник записываем код символа Sour:=Pos(StringValue[N],base64ABC)-1; //делаем побитный сдвиг влево для чисел источник и премник Sour:=Sour SHL M; Dest:=Dest SHL 1; //смотрим старший (шестой) бит 6-ти битного числа-источника //если бит установлен, то устанавливаем меньший бит числа-преимника If (Sour And 32)=32 Then Dest:=Dest Or 1; //увеличиваем счетчик побитной обработки 8-ми битного числа Inc(NextNum); //если обработаны все восемь бит If NextNum > 8 Then Begin {If NextNum} //обнуляем флаг-счетчик NextNum:=1; //записываем в массив полученный байт Result.ByteArr[CurPos]:=Dest; //если обрабатывался символ "знак отсутствия байта" If StringValue[N]='=' Then //обнулим полученный байт Result.ByteArr[CurPos]:=0 Else //иначе, увеличим счетчик считанных байтов Result.ByteCount:=CurPos+1; //будем обрабатывать следующий байт в массиве байтов TBase64.ByteArr Inc(CurPos); Dest:=0; End; {If NextNum} End; {For M} End; {For N} End; {DecodeBase64} //================================DecodeBase64================================== end.