Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.08.2008, 22:55   #1
furstenberg
Форумчанин
 
Регистрация: 08.10.2007
Сообщений: 125
По умолчанию кодировать в base64

Здравствуйте, подскажите пожайлуста как закодировать бинарный файл в base64?
furstenberg вне форума Ответить с цитированием
Старый 28.08.2008, 23:43   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Вот для строк. Но думаю перевести из String в Pointer не составит труда...
Хотя даже зачем вообще переводить...прочитали в PChar ваш бинарник и пихнули в эти процедуры )) вот и все
Код:
const
  b64alphabet: PChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

function EncodeBase64(Value: String): String;
const
  pad: PChar = '====';

  function EncodeChunk(const Chunk: String): String;
  var
    W: LongWord;
    i, n: Byte;
  begin
    n := Length(Chunk); W := 0;
    for i := 0 to n - 1 do
      W := W + Ord(Chunk[i + 1]) shl ((2 - i) * 8);
    Result := b64alphabet[(W shr 18) and $3f] +
              b64alphabet[(W shr 12) and $3f] +
              b64alphabet[(W shr 06) and $3f] +
              b64alphabet[(W shr 00) and $3f];
    if n <> 3 then
      Result := Copy(Result, 0, n + 1) + Copy(pad, 0, 3 - n);   //add padding when out len isn't 24 bits
  end;

begin
  Result := '';
  while Length(Value) > 0 do
  begin
    Result := Result + EncodeChunk(Copy(Value, 0, 3));
    Delete(Value, 1, 3);
  end;
end;

function DecodeBase64(Value: String): String;

  function DecodeChunk(const Chunk: String): String;
  var
    W: LongWord;
    i: Byte;
  begin
    W := 0; Result := '';
    for i := 1 to 4 do
      if Pos(Chunk[i], b64alphabet) <> 0 then
        W := W + Word((Pos(Chunk[i], b64alphabet) - 1)) shl ((4 - i) * 6);
    for i := 1 to 3 do
      Result := Result + Chr(W shr ((3 - i) * 8) and $ff);
  end;
  
begin
  Result := '';
  if Length(Value) mod 4 <> 0 then Exit;
  while Length(Value) > 0 do
  begin
    Result := Result + DecodeChunk(Copy(Value, 0, 4));
    Delete(Value, 1, 4);
  end;
end;
BOBAH13 вне форума Ответить с цитированием
Старый 28.08.2008, 23:59   #3
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Глянь тут http://www.swissdelphicenter.ch/en/showcode.php?id=1524

ДОБАВЛЕНО

BOBAH13, долго не обновлял страницу, приношу извинения.

Последний раз редактировалось eoln; 29.08.2008 в 00:19.
eoln вне форума Ответить с цитированием
Старый 29.08.2008, 00:14   #4
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от eoln Посмотреть сообщение
Интересно, а что я выше написал ? сорри за оффтоп... просто начинается раздутие темы
BOBAH13 вне форума Ответить с цитированием
Старый 29.08.2008, 00:42   #5
furstenberg
Форумчанин
 
Регистрация: 08.10.2007
Сообщений: 125
По умолчанию

Для строк всё работает нормально, но если файл содержит бинарные символы ничего не получается. Допустим если файл весит 2 метра и мы его кодируем его, то на выходе получается 100 байт. Надо какую то использовать функцию , на вход которой мы подаём данные не в виде строки. Я нашёл в стандартных компонентах компонент IdEncoderMIME:
IdEncoderMIME1.Encode(Tstream,integ er):string; только использовать его не получается
furstenberg вне форума Ответить с цитированием
Старый 29.08.2008, 01:16   #6
furstenberg
Форумчанин
 
Регистрация: 08.10.2007
Сообщений: 125
По умолчанию

Цитата:
Хотя даже зачем вообще переводить...прочитали в PChar ваш бинарник и пихнули в эти процедуры )) вот и все
Записываем в Pchar:
var
p: PChar;
s:string;
begin
GetMem(p, 255);
with TFileStream.create('D:\temp\1\1', fmOpenReadWrite) do
try
Seek(10, soFromBeginning);
read(p^, 254);
finally
free;
end;

FreeMem(p);
end;
файл 1 весит > 2 метров , а в Pchar записывается только три символа?
furstenberg вне форума Ответить с цитированием
Старый 29.08.2008, 09:23   #7
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Ооо.. ну вам еще учиться и учиться Писал сразу тут, за не корректность извините
И что же в вашем понятии "бинарные" символы )) а они бывают и не бинарными ?

Код:
var
  p, s: PCHAR;
  l: Integer;
  f: File;
begin
  AssignFile(f, 'file.bin');
  Reset(f, 1);
  l := FileSize(f);
  GetMem(p, l);
  BlockRead(f, p^, l);
  CloseFile(f);
  
  // тут de или en code base64 пихая сразу p а не String
  // и пишем s := Encode.. т.е. получаем тоже PCHAR, хотя можно и String думаю

  FreeMem(p, l);
Вот и все... должно пахать
BOBAH13 вне форума Ответить с цитированием
Старый 29.08.2008, 09:52   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

да расслабьтесь, пацаны. ничего у вас с PChar не получится.... :-)
из хелпа на PChar
Цитата:
These character pointers are used to manipulate null-terminated strings. (See Working with null-terminated strings.)
заметили, где подвох? ;-)

Цитата:
Сообщение от furstenberg
а в Pchar записывается только три символа?
в PChar у Вас считваются все ваши 254 байта, но остаются только все до первого нулевого байта. т.е. в Вашем файле три байта от смещения 10 есть, а четвёртый - 0x00 ($00)

рекомендую заменить на обычный статический Array:
Код:
var
  p: PChar;
  buf : array[1..255] of byte;
  k : integer;
begin
  with TFileStream.create('D:\temp\1\1', fmOpenReadWrite) do
  try
    Seek(10, soFromBeginning);
    k := read(buf, 254);
  finally
    free;
  end;
end;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.08.2008, 13:02   #9
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Классно пошутили Скажите какая разница между PChar и Pointer ? Когда скажите тогда и поговорим.... В том то и дело что никакой... что PChar указатель на байт что Pointer что оба они это всеголишь 32 битное число... и то что вы приводите справку из дельфи что типа если попытаться преобразовать Stirng(PChar()) то получите строку начиная с байта на который указывает PChar и закончится строка когда встретится нулевой байт. А мы говорим не о строках, а о данных выделенных в памяти... И вы подразумиваите что в 32х битной системе защищенного режима нельзя выделить память больше чем 255 т.к. вы указали тип PChar и не Pointer ? Короче бред...
BOBAH13 вне форума Ответить с цитированием
Старый 29.08.2008, 13:28   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

BOBAH13, умничаем, да?? :-))))
в том то и дело, что если бы вместо PChar был Pointer - то всё было бы отлично! но это немножечко разные вещи. я же привёл цитату из хелпа про PChar!

не согласны? ну тогда ответьте на два простых вопроса:
1) почему не работал код из поста #6
2) что будет после выполнения кода
Код:
var
  p : PChar;
begin
  p := '123'#0'456789';
  ShowMessage( IntToStr(StrLen(p)) );
  Move(p^,buf[1],5);
  ShowMessage(string(buf));
end;
3) в вышеуказанном коде покажите, как можно получить символы '4' '5' и т.д. из области памяти, на которую указывает p (PChar - это же указатель)...

и последнее. BOBAH13, я вижу,читаю Ваши посты. Поэтому НИ МАЛЕЙШЕГО сомнения в Вашей компетентности у меня нет. Просто, думаю, тут наложилось знание многих языков и внутренностей ОС...
многия знания - многия печали :-)
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
base64 BlackOmen Общие вопросы Delphi 2 02.05.2008 16:30