Давно что-то не было статей. В общем, исправляемся 🙂
В Delphi 6 был хороший компонентик — TNMURL, но начиная с Delphi 7 эти компоненты заменили Indy. И теперь, чтобы кодировать и декодировать кириллицу в Дельфи нужно облазить весь инет, если удастся найти нужные функции — они не будут работать у людей, которые используют Delphi 2007 и выше. Предлагаю вашему вниманию переписанный вариант этих функций.
Значит, выглядят они так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
{ **** UBPFD *********** by delphibase.endimus.com **** >> URL кодирование строки Зависимости: Windows Автор: Dimka Maslov, mainbox@endimus.ru, ICQ:148442121, Санкт-Петербург Copyright: Dimka Maslov Дата: 27 мая 2002 г. ***************************************************** } function UrlEncode(Str: string): string; function CharToHex(Ch: Char): Integer; asm and eax, 0FFh mov ah, al shr al, 4 and ah, 00fh cmp al, 00ah jl @@10 sub al, 00ah add al, 041h jmp @@20 @@10: add al, 030h @@20: cmp ah, 00ah jl @@30 sub ah, 00ah add ah, 041h jmp @@40 @@30: add ah, 030h @@40: shl eax, 8 mov al, '%' end; var i, Len: Integer; Ch: Char; N: Integer; P: PChar; begin Result := ''; Len := Length(Str); P := PChar(@N); for i := 1 to Len do begin Ch := Str[i]; if Ch in ['0'..'9', 'A'..'Z', 'a'..'z', '_'] then Result := Result + Ch else begin if Ch = ' ' then Result := Result + '+' else begin N := CharToHex(Ch); Result := Result + P; end; end; end; end; function UrlDecode(Str: string): string; function HexToChar(W: word): Char; asm cmp ah, 030h jl @@error cmp ah, 039h jg @@10 sub ah, 30h jmp @@30 @@10: cmp ah, 041h jl @@error cmp ah, 046h jg @@20 sub ah, 041h add ah, 00Ah jmp @@30 @@20: cmp ah, 061h jl @@error cmp al, 066h jg @@error sub ah, 061h add ah, 00Ah @@30: cmp al, 030h jl @@error cmp al, 039h jg @@40 sub al, 030h jmp @@60 @@40: cmp al, 041h jl @@error cmp al, 046h jg @@50 sub al, 041h add al, 00Ah jmp @@60 @@50: cmp al, 061h jl @@error cmp al, 066h jg @@error sub al, 061h add al, 00Ah @@60: shl al, 4 or al, ah ret @@error: xor al, al end; function GetCh(P: PChar; var Ch: Char): Char; begin Ch := P^; Result := Ch; end; var P: PChar; Ch: Char; begin Result := ''; P := @Str[1]; while GetCh(P, Ch) <> #0 do begin case Ch of '+': Result := Result + ' '; '%': begin Inc(P); Result := Result + HexToChar(PWord(P)^); Inc(P); end; else Result := Result + Ch; end; Inc(P); end; end; |
Теперь переписаный вариант, который работает в Delphi XE (грубо говоря, переписывание заключалось в этом «String -> AnsiString, Char — AnsiChar, PChar — PAnsiChar»):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
function UrlEncode(Str: ansistring): ansistring; function CharToHex(Ch: ansiChar): Integer; asm and eax, 0FFh mov ah, al shr al, 4 and ah, 00fh cmp al, 00ah jl @@10 sub al, 00ah add al, 041h jmp @@20 @@10: add al, 030h @@20: cmp ah, 00ah jl @@30 sub ah, 00ah add ah, 041h jmp @@40 @@30: add ah, 030h @@40: shl eax, 8 mov al, '%' end; var i, Len: Integer; Ch: ansiChar; N: Integer; P: PansiChar; begin Result := ''; Len := Length(Str); P := PansiChar(@N); for i := 1 to Len do begin Ch := Str[i]; if Ch in ['0'..'9', 'A'..'Z', 'a'..'z', '_'] then Result := Result + Ch else begin if Ch = ' ' then Result := Result + '+' else begin N := CharToHex(Ch); Result := Result + P; end; end; end; end; function UrlDecode(Str: Ansistring): Ansistring; function HexToChar(W: word): AnsiChar; asm cmp ah, 030h jl @@error cmp ah, 039h jg @@10 sub ah, 30h jmp @@30 @@10: cmp ah, 041h jl @@error cmp ah, 046h jg @@20 sub ah, 041h add ah, 00Ah jmp @@30 @@20: cmp ah, 061h jl @@error cmp al, 066h jg @@error sub ah, 061h add ah, 00Ah @@30: cmp al, 030h jl @@error cmp al, 039h jg @@40 sub al, 030h jmp @@60 @@40: cmp al, 041h jl @@error cmp al, 046h jg @@50 sub al, 041h add al, 00Ah jmp @@60 @@50: cmp al, 061h jl @@error cmp al, 066h jg @@error sub al, 061h add al, 00Ah @@60: shl al, 4 or al, ah ret @@error: xor al, al end; function GetCh(P: PAnsiChar; var Ch: AnsiChar): AnsiChar; begin Ch := P^; Result := Ch; end; var P: PAnsiChar; Ch: AnsiChar; begin Result := ''; P := @Str[1]; while GetCh(P, Ch) <> #0 do begin case Ch of '+': Result := Result + ' '; '%': begin Inc(P); Result := Result + HexToChar(PWord(P)^); Inc(P); end; else Result := Result + Ch; end; Inc(P); end; end; |
Использовать так:
1 2 |
Edit1.Text:=UrlEncode(AnsiToUtf8('тест')); Edit2.Text:=Utf8ToAnsi(UrlDecode(Edit1.Text)); |
Отличная статья!
Под Delphi xe 2 не работает. Подскажите в чём могут быть проблемы?
Как это не работает? О_о Я на ней сижу и прекрасно работает.
Ошибку пишет http://s40.radikal.ru/i089/1112/db/b90d80f88140.png
Я же написал, как использовать (с конвертом в утф8 и обратно):
Edit1.Text:=UrlEncode(AnsiToUtf8(‘тест’));
Edit2.Text:=Utf8ToAnsi(UrlDecode(Edit1.Text));
Если все равно ошибка — исходник скиньте.
Я так и использовал, не работает. Вот исходник http://stimulus-project.ru/project.zip
В общем, Build Configurations установите в «Release», компильните и… все будет нормально 🙂
http://shot.photo.qip.ru/00419o-3048CtA/
Спасибо теперь всё работает как часы.
Под Delphi xe 3 то что доктор прописал, спасибо большое !
Delphi XE.
Всё работает. Спасибо.
Под Delphi 2010 замечательно работает версия для XE. Спасибо!
На Delphi XE10 ругается на строке:
while GetCh(P, Ch) <> #0 do
пишет:
[dcc32 Error] Unit1.pas(177): E2012 Type of expression must be BOOLEAN
Всё исправилось когда вместо символов написал угольные скобки:
uses
IdURI;
..
begin
S := TIdURI.URLEncode(str);
//
S := TIdURI.URLDecode(str);
end;