Unit UrlEncode; Interface Function RawUrlEncode(S : String) : String; Function RawUrlDecode(S : String) : String; Implementation { This is based on the PHP function of the same name: http://us2.php.net/manual/en/function.rawurlencode.php rawurlencode -- URL-encode according to RFC 1738 A space is encoded just like most special characters, in hex, not as a '+' } Function RawUrlEncode(S : String) : String; Const HexDigit = '0123456789ABCDEF'; UnchangedChars = ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '.']; Var FromIndex, ToIndex : Integer; Begin ToIndex := Length(S); For FromIndex := 1 To Length(S) Do If Not (S[FromIndex] In UnchangedChars) Then ToIndex := ToIndex + 2; SetLength(Result, ToIndex); ToIndex := 1; For FromIndex := 1 To Length(S) Do If S[FromIndex] In UnchangedChars Then Begin Result[ToIndex] := S[FromIndex]; Inc(ToIndex) End Else Begin Result[ToIndex] := '%'; Inc(ToIndex); Result[ToIndex] := HexDigit[Succ((Ord(S[FromIndex]) ShR 4) And $f)]; Inc(ToIndex); Result[ToIndex] := HexDigit[Succ(Ord(S[FromIndex]) And $f)]; Inc(ToIndex) End End; { This is based on the PHP function of the same name: http://us2.php.net/manual/en/function.rawurldecode.php rawurldecode -- Decode URL-encoded strings I don't know why there are two different standards. For the most compatibility encode with RawUrlEncode and decode with plain UrlDecode http://us2.php.net/manual/en/function.urldecode.php } Function RawUrlDecode(S : String) : String; Function UnHex(C : Char) : Integer; Begin If C In ['0'..'9'] Then Result := Ord(C) - Ord('0') Else Result := (Ord(C) And $DF) - Ord('A') + 10 End; Const ValidHexChars = ['0'..'9', 'A'..'F', 'a'..'f']; Var FromIndex, ToIndex : Integer; Begin FromIndex := 1; ToIndex := 1; SetLength(Result, Length(S)); While FromIndex <= Length(S) Do Begin If (S[FromIndex] = '%') And (S[Succ(FromIndex)] In ValidHexChars) And (S[FromIndex + 2] In ValidHexChars) Then Begin Result[ToIndex] := Chr(UnHex(S[Succ(FromIndex)]) ShL 4 + UnHex(S[FromIndex + 2])); FromIndex := FromIndex + 3 End Else Begin Result[ToIndex] := S[FromIndex]; Inc(FromIndex) End; Inc(ToIndex) End; SetLength(Result, Pred(ToIndex)) End; End.