URLEncode и URLDecode в Delphi
При написании программ, взаимодействующих по сети, иногда встает проблема передачи, приема и распознавания символов локального алфавита. Например, при написании клиента для некоего сайта. Мы, собственно, наталкиваемся на отсутствие в Delphi функций URLEncode и URLDecode. Поэтому приходится их писать самим. Ниже приведены упомянутые функции. Чтобы лишний раз не изобретать велосипед.
DELPHI:
-
function DigitToHex(Digit: Integer): Char;
-
begin
-
case Digit of
-
0..9: Result := Chr(Digit + Ord('0'));
-
10..15: Result := Chr(Digit - 10 + Ord('A'));
-
else
-
Result := '0';
-
end;
-
end; // DigitToHex
-
-
function URLEncode(const S: string): string;
-
var
-
i, idx, len: Integer;
-
begin
-
len := 0;
-
for i := 1 to Length(S) do
-
if ((S[i] >= '0') and (S[i] <= '9')) or
-
((S[i] >= 'A') and (S[i] <= 'Z')) or
-
((S[i] >= 'a') and (S[i] <= 'z')) or (S[i] = ' ') or
-
(S[i] = '_') or (S[i] = '*') or (S[i] = '-') or (S[i] = '.') then
-
len := len + 1
-
else
-
len := len + 3;
-
SetLength(Result, len);
-
idx := 1;
-
for i := 1 to Length(S) do
-
if S[i] = ' ' then
-
begin
-
Result[idx] := '+';
-
idx := idx + 1;
-
end
-
else if ((S[i] >= '0') and (S[i] <= '9')) or
-
((S[i] >= 'A') and (S[i] <= 'Z')) or
-
((S[i] >= 'a') and (S[i] <= 'z')) or
-
(S[i] = '_') or (S[i] = '*') or (S[i] = '-') or (S[i] = '.') then
-
begin
-
Result[idx] := S[i];
-
idx := idx + 1;
-
end
-
else
-
begin
-
Result[idx] := '%';
-
Result[idx + 1] := DigitToHex(Ord(S[i]) div 16);
-
Result[idx + 2] := DigitToHex(Ord(S[i]) mod 16);
-
idx := idx + 3;
-
end;
-
end; // URLEncode
-
-
function URLDecode(const S: string): string;
-
var
-
i, idx, len, n_coded: Integer;
-
function WebHexToInt(HexChar: Char): Integer;
-
begin
-
if HexChar < '0' then
-
Result := Ord(HexChar) + 256 - Ord('0')
-
else if HexChar <= Chr(Ord('A') - 1) then
-
Result := Ord(HexChar) - Ord('0')
-
else if HexChar <= Chr(Ord('a') - 1) then
-
Result := Ord(HexChar) - Ord('A') + 10
-
else
-
Result := Ord(HexChar) - Ord('a') + 10;
-
end;
-
begin
-
len := 0;
-
n_coded := 0;
-
for i := 1 to Length(S) do
-
if n_coded >= 1 then
-
begin
-
n_coded := n_coded + 1;
-
if n_coded >= 3 then
-
n_coded := 0;
-
end
-
else
-
begin
-
len := len + 1;
-
if S[i] = '%' then
-
n_coded := 1;
-
end;
-
SetLength(Result, len);
-
idx := 0;
-
n_coded := 0;
-
for i := 1 to Length(S) do
-
if n_coded >= 1 then
-
begin
-
n_coded := n_coded + 1;
-
if n_coded >= 3 then
-
begin
-
Result[idx] := Chr((WebHexToInt(S[i - 1]) * 16 +
-
WebHexToInt(S[i])) mod 256);
-
n_coded := 0;
-
end;
-
end
-
else
-
begin
-
idx := idx + 1;
-
if S[i] = '%' then
-
n_coded := 1;
-
if S[i] = '+' then
-
Result[idx] := ' '
-
else
-
Result[idx] := S[i];
-
end;
-
end; // URLDecode


May 25th, 2007 at 11:50 Quote
Вполне даже аккуратненько
Особенно порадовало что размер строки вычисляешь СНАЧАЛА
С другой стророны два раза ходить по массиву...
А не пробовал выделить строку с запасом (например при кодировании - утроить исходную длину) а потом уменьшить размер через SetLength?
И ещё одно замечание - в случае, например, русского алфавита этот код будет работать только если кодировки на сервере и клиенте совпадают. Не забываем что вообще-то на сервере может быть настройка Response/Request encoding = unicode
May 25th, 2007 at 12:06 Quote
я сильно не люблю SetLength. потому и не использую :)
а про unicode - собственно, я везде и всегда использую только unicode. забыл написать.
August 12th, 2007 at 20:48 Quote
в модуле idGlobal есть готовые URLEncode/URLDecode
August 13th, 2007 at 06:38 Quote
kerya @ 12.08.2007, 20:48 #
хм. что-то не вижу. и ои не документированы, если и есть.