Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];

Вниз

Base64 кодирование и UnicodeString   Найти похожие ветки 

 
DVM ©   (2008-09-30 12:19) [0]

Никак не пойму как правильно закодировать в Base64 Unicode строку (ту что в Delphi 2009 теперь string).

Т.е. допустим имеем строку

var s: string;
...
s:="йцукен";
Беру TIdEncoderMIME из Indy что в Delphi 2009, кодирую получаю:
OUZDOjU9

Как так может быть, ведь строка занимает 12 байт, а не 6 ?

Тот же самый кодер для строки qwerty дает cXdlcnR5.

В Indy ошибка или нет?

Unicode строку надо кодировать как буфер с длиной Length(s) * SizeOf(Char) или как то по другому?


 
tytus   (2008-09-30 13:44) [1]

Не знаю как в Indy10, потому как не кодировал в Base64,
но размер буфера нужно выделять как
Length(s)*SizeOf(WideChar)+1

По умолчанию в D2009 String уже UnicodeString, поэтому если нужно
использовать однобайтовую строку, то описывать нужно как AnsiString


 
DVM ©   (2008-09-30 13:55) [2]


> но размер буфера нужно выделять как
> Length(s)*SizeOf(WideChar)+1

Я не выделяю память. Length(s) * SizeOf(Char) - это количество памяти, занимаемое Unicode строкой.


> По умолчанию в D2009 String уже UnicodeString, поэтому если
> нужно
> использовать однобайтовую строку, то описывать нужно как
> AnsiString

Да это понятно, с Ansistring проблем нет, кроме кучи варнингов насчет потенциально возможной потери данных.


 
Anatoly Podgoretsky ©   (2008-09-30 14:17) [3]

> DVM  (30.09.2008 12:19:00)  [0]

Для Base64 совсем не важно строка ли это и если строка, то какого типа. Base64 не строковая функция.


 
DVM ©   (2008-09-30 14:25) [4]


> Anatoly Podgoretsky ©   (30.09.08 14:17) [3]


> Base64 не строковая функция.

это я понимаю, получается Indy кодирует неправильно, т.к. из шести символов Unicode строки (12 байт) не может получиться 8 символов AnsiChar (8 байт). А вот получается.

Кстати, а WEB сервера принимают GET запросы только в однобайтной кодировке?


 
Anatoly Podgoretsky ©   (2008-09-30 15:17) [5]

> DVM  (30.09.2008 13:55:02)  [2]

Вообще то это размер любой строки, как Юникод, так и нет, и если заменить char на тип, то это будет работать и для динамических массивов.

AnsiString надо было использовать и ранее и это не связано с Д2009, по крайней мере это описано уже в Д2


 
Eraser ©   (2008-09-30 15:18) [6]

хм..
на C# подобный код вернул "OQRGBEMEOgQ1BD0E".

       private void button1_Click(object sender, EventArgs e)
       {
           string s1 = "йцукен";

           // Кодирование.
           byte[] toEncodeAsBytes = System.Text.UnicodeEncoding.Unicode.GetBytes(s1);
           textBox1.Text = Convert.ToBase64String(toEncodeAsBytes);

           // Декодирование.
           toEncodeAsBytes = Convert.FromBase64String(textBox1.Text);
           s1 = System.Text.UnicodeEncoding.Unicode.GetString(toEncodeAsBytes);
           MessageBox.Show(s1);
       }

очень странно, вроде Indy работает с string (в т.ч. записывает в поток), нигде упоминаний про ansistring не видел...


 
Anatoly Podgoretsky ©   (2008-09-30 15:19) [7]

> DVM  (30.09.2008 14:25:04)  [4]

Инди кодирует правильно, проверено опытами. Это ты что то неправильно делаешь, должно получиться 16 байт, но не AnsiChar - а просто 16 байт в формате Base64


 
Anatoly Podgoretsky ©   (2008-09-30 15:21) [8]

Простой вопрос, может ламерский, а Дельфи у тебя какая?


 
Eraser ©   (2008-09-30 15:45) [9]

вот корректный код для Делфи.
procedure TForm1.Button1Click(Sender: TObject);
var
 s1: string;
 Bytes: TBytes;
begin
 s1 := "йцукен";

 // Кодирование.
 Bytes := TEncoding.Unicode.GetBytes(s1);
 s1 := IdEncoderMIME1.EncodeBytes(Bytes);
 ShowMessage(s1);

 // Декодирование.
 Bytes := IdDecoderMIME1.DecodeBytes(s1);
 s1 := TEncoding.Unicode.GetString(Bytes);
 ShowMessage(s1);
end;


 
Anatoly Podgoretsky ©   (2008-09-30 16:14) [10]

> Eraser  (30.09.2008 15:18:06)  [6]

Инди не работает с Юникод, но и Base64 не имеет никакого отношения к Юникод.


 
DVM ©   (2008-09-30 18:07) [11]


> Anatoly Podgoretsky ©   (30.09.08 15:19) [7]
>
> > DVM  (30.09.2008 14:25:04)  [4]
>
> Инди кодирует правильно, проверено опытами. Это ты что то
> неправильно делаешь, должно получиться 16 байт, но не AnsiChar
> - а просто 16 байт в формате Base64
>

судя по описанию функции должен получиться на выходе кодера именно string.


> Простой вопрос, может ламерский, а Дельфи у тебя какая?

2009.


> Eraser ©   (30.09.08 15:45) [9]
>
> вот корректный код для Делфи.

Так, да все верно выходит, то же самое можно и по старинке типа того:

var
s1: string;
Bytes: PAnsiChar;
begin
s1 := "йцукен";
GetMem(Bytes, Length(s1) * SizeOf(Char));
try
  Move(s1, Bytes, Length(s1) * SizeOf(Char));
  ShowMessage(IdEncoderMIME1.EncodeString(Bytes));
finally
  FreeMem(Bytes, Length(s1) * SizeOf(Char));
end;
end;


но почему так вот неверно мне чего-то не понятно:

procedure TForm1.Button1Click(Sender: TObject);
begin
 edit2.Text := IdEncoderMIME1.EncodeString(edit1.text);
end;

Т.е. выходит Indy не поддерживает Unicode.


 
DVM ©   (2008-09-30 18:09) [12]

Т.е. в библиотеках Indy не поправили код насчет Unicode.

А вот зато стандартный дельфовый EncdDecd поправили. С ним нет проблем.


 
Anatoly Podgoretsky ©   (2008-09-30 19:17) [13]


> Т.е. выходит Indy не поддерживает Unicode.

Может и не поддерживает, поскольку Инди это не Дельфи, а взят на халяву у Nevrona.
Надо смотреть исходники функции TIdEncoderMIME


 
Eraser ©   (2008-09-30 20:19) [14]

> [12] DVM ©   (30.09.08 18:09)

так точно.
проблема тут
function TIdEncoder.Encode(const AIn: string): string;
var
 LStream: TMemoryStream;
begin
 if AIn<>"" then  begin
   LStream := TMemoryStream.Create;
   try
     IdGlobal.WriteStringToStream(LStream,AIn, en8bit); // <<-------------------
     LStream.Position := 0;
     Result := Encode(LStream);
   finally
     FreeAndNil(LStream);
   end;
 end else begin
   Result := "";
 end;
end;



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.005 c
15-1252842870
_Андрей
2009-09-13 15:54
2009.11.08
инет в Viste


1-1222978239
DmitriyG.
2008-10-03 00:10
2009.11.08
Программное получение стека


15-1252557641
test
2009-09-10 08:40
2009.11.08
Обратная совместимость


1-1222762776
DVM
2008-09-30 12:19
2009.11.08
Base64 кодирование и UnicodeString


15-1252688079
test
2009-09-11 20:54
2009.11.08
День граненого стакана





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский