Форум: "Основная";
Текущий архив: 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.007 c