Другие языки программирования и технологии

Pascal | URL Encode\Decode | UTF-8

Имееься строка, или массив типа чар примерно вот такого содержания:
АБВГДЕЖЗИЙК

Нужно преобразовать это к UnicodeString
Перевожу кусочек строки из хекса в инт
Function HexToInt(s16: string): int64;
Var
i, k: Byte;
Begin
Result:=0;
for i:= 1 to Length(s16) do
begin
case s16 of
'0'..'9': k:=Ord(s16)-48;
'A'..'F': k:=Ord(s16)-55;
'a'..'f': k:=Ord(s16)-87;
end;
Result += k * Trunc(Power(16,Length(s16)-i));
end;
End;
Например получаю я DO , 90 (или 208, 144 в десятичной) а как их скрестить чтоб получить Unicod символ 1040
function URL_To_Unicode(s:string):WideString;
var Buffer:string;
n:integer;
begin
Buffer:='';
n:=1;
while n <= length(s) do
begin
if s[n] <> '%' then
Buffer:=Buffer+s[n]
else
begin
Buffer:=Buffer+chr(StrToInt('$'+s[n+1]+s[n+2]));
inc(n,2)
end;
inc(n)
end;
Result:=Utf8Decode(Buffer);
end;

function Unicode_To_URL(s:WideString):string;
var Buffer:string;
n:integer;
begin
Buffer:=Utf8Encode(s);
Result:='';
for n:=1 to length(Buffer) do
if Buffer[n] in ['0'..'9','A'..'Z','a'..'z',':','/','.','?','=','&','#'] then
{при необходимости добавьте в множество символы, которые также разрешены в адресе}
Result:=Result+Buffer[n]
else
Result:=Result+'%'+IntToHex(ord(Buffer[n]),2);
end;

Если использование библиотечных функций StrToInt, IntToHex, Utf8Encode и Utf8Decode невозможно (или нет желания из-за большого размера модуля SysUtils), то упрощённая реализация этих функций (не совсем корректно происходит самосинхронизация UTF-8 при потере байтов) :

function StrToInt(s:string):integer;
var e:integer;
begin
val(s,Result,e);
end;

function IntToHex(d,n:integer):string;
function HexDigit(x:byte):char;
begin
Result:=chr(x+$30+ord(x > 9)*7);
end;
var i:integer;
begin
Result:='';
for i:=1 to n do
begin
Result:=HexDigit(d and $F)+Result;
d:=d shr 4;
end;
end;

function Utf8Decode(s:string):WideString;
var c,d,n,k,m,r,q:word;
begin
Result:='';
n:=1;
d:=0;
while n <= length(s) do
begin
c:=ord(s[n]);
if c < $80 then
begin
Result:=Result+WideChar(c);
d:=0
end
else
begin
if d=0 then
begin
q:=c;
k:=0;
m:=$7F;
r:=7;
while q and $80 <> 0 do
begin
inc(k);
dec(r);
q:=q shl 1;
m:=m shr 1
end
end;
if d <> 0 then
d:=d shl r;
d:=d or c and m;
dec(k);
r:=6;
m:=$3F;
if (k=0) or (n=length(s)) then
begin
Result:=Result+WideChar(d);
d:=0
end;
end;
inc(n)
end;
end;

function Utf8Encode(s:WideString):string;
var c,n:word;
begin
Result:='';
for n:=1 to length(s) do
begin
c:=ord(s[n]);
case c and $FF80 of
0: Result:=Result+Char(c);
$80..$7FF: Result:=Result+Char($C0 or (c shr 6) and $1F)+Char($80 or c and $3F);
else
Result:=Result+Char($E0 or (c shr 12) and $F)+Char($80 or (c shr 6) and $3F)
+Char($80 or c and $3F);
end;
end;
end;
ОМ
Олег Мартынов
51 590
Лучший ответ