RAD Studio 10.4.1关于Rest应用中字符串的编码解码及delphi处理html乱码问题

目录

RAD Studio 10.4.1关于Rest应用中字符串的编码解码及delphi处理html乱码问题

一、与www相关的编码与解码方法

1.1、System.NetEncoding.pas

1.1.1、TNetEncoding.Base64格式

1.1.2、TNetEncoding.HTML格式

1.1.3、TNetEncoding.URL格式

1.1.4、关于TNetEncoding其它可用的转化函数

1.2、Web.HTTPApp.pas

1.3、IdStrings.pas

 1.4、关于网页html乱码

二、进制转化

2.1、16进制string转10进制整数int

2.2、10进制整数int转16进制string

2.3、16进制和2进制互转


RAD Studio 10.4.1关于Rest应用中字符串的编码解码及delphi处理html乱码问题

一、与www相关的编码与解码方法

1.1、System.NetEncoding.pas

1.1.1、TNetEncoding.Base64格式

        常被用于图片二进制码字符串(字节流)的编解码等:

        应用1:将图片写入到数据库通用字段类型Blob,拿到图片的16进制字符串,前面再加上X,才可以Insert或Update为Blob字段类型;TBlobField(ABlob:TField).SaveToStream(AMemoryStream);  

        应用2:图片在互联网上Json传输后的Rest转化:

  TBytes = TArray<Byte>;  //:可以强制转化一下:array of Byte
        Input :=
                TBytesStream.LoadFromFile(FileName).Bytes;
//或用TBytesStream的子类TStringStream,TBytesStream的父类为内存流TMemoryStream:
        Input :=
                TStringStream.LoadFromFile(FileName).Bytes;
        Output1 :=
                TNetEncoding.Base64.Encode(Input: array of Byte): string;  //Base64编码
        Output2 :=
                TNetEncoding.Base64.Decode(Output1 ): string;  //Base64解码
        Output_FileBytes :=
                TNetEncoding.Base64.DecodeStringToBytes(Output2 ): TBytes;  //Base64解码
        TStringStream.Create(Output_FileBytes);
        TStringStream.SaveToFile(Output_File: string);

//若使用TStringStream,不要再多此一举地:
        Input :=
                TStringStream.LoadFromFile(FileName).DataString;
        Output1  :=
                TNetEncoding.Base64.Decode(Input): string;  //Base64编码
//因为还涉及到只读属性TStringStream.Encoding: TEncoding问题;很多同学经常这样使用,否则你还得去判断字串符的TEncoding编码格式

//若使用TStringStream,不要再多此一举地:
        Input :=
                TStringStream.LoadFromFile(FileName).DataString;
        Output1  :=
                TNetEncoding.Base64.Decode(Input): string;  //Base64编码
//因为还涉及到只读属性TStringStream.Encoding: TEncoding问题;很多同学经常这样使用,否则你还得去判断字串符的TEncoding编码格式

1.1.2、TNetEncoding.HTML格式

        常被用于对HTML文档代码的编解码等:

        TNetEncoding.HTML.Encode(const Input: string): string;  //HTML编码

        TNetEncoding.HTML.Decode(const Input: string): string;  //HTML解码

1.1.3、TNetEncoding.URL格式

        常被用于对URL代码的编解码等:

        TNetEncoding.URL.Encode(const Input: string): string;  //URL编码:URL: TURLEncoding;

        TNetEncoding.URL.Decode(const Input: string): string;  //URL解码:URL: TURLEncoding;

    function URLDecode(const AValue: string): string; inline;
        //:解码URL编码的字符串:内联
    function EncodeAuth(const Auth: string; const AExtraUnsafeChars: TUnsafeChars = []): string; inline;
        //:编码验证:内联
    function EncodeQuery(const AQuery: string; const AExtraUnsafeChars: TUnsafeChars = []): string; inline;
        //:编码Get查询参数:内联
    function EncodeForm(const AInput: string; const AExtraUnsafeChars: TUnsafeChars = []; AEncoding: TEncoding = nil): string; inline;
        //:编码表单:内联
    function FormDecode(const AValue: string; AEncoding: TEncoding = nil): string; inline;
        //:解码表单:内联

    function EncodePath(const APath: string; const AExtraUnsafeChars: TUnsafeChars = []): string;
        //:编码路径

    function Encode(const AInput: string; const ASet: TUnsafeChars; const AOptions: TEncodeOptions; AEncoding: TEncoding = nil): string; overload;
        //:URL编码
    function Decode(const AValue: string; const AOptions: TDecodeOptions; AEncoding: TEncoding = nil): string; overload;
        //:解码URL编码的字符串

        不安全的字符有哪些:

  TURLEncoding = class(TNetEncoding)
  public
  type
//:不安全的字符:
    //UnsafeChar = 32..127;
    UnsafeChar = Byte;
    TUnsafeChars = set of UnsafeChar;
    TEncodeOption = (SpacesAsPlus, EncodePercent);
    TEncodeOptions = set of TEncodeOption;
    TDecodeOption = (PlusAsSpaces);
    TDecodeOptions = set of TDecodeOption;

        不安全的字符的序数:

    const FormUnsafeChars: TUnsafeChars = [Ord('"'), Ord(''''), Ord(':'), Ord(';'), Ord('<'), Ord('='), Ord('>'),
      Ord('@'), Ord('['), Ord(']'), Ord('^'), Ord('`'), Ord('{'), Ord('}'), Ord('|'), Ord('/'), Ord('\'), Ord('?'), Ord('#'),
      Ord('&'), Ord('!'), Ord('$'), Ord('('), Ord(')'), Ord(','), Ord('~')];
    const AuthUnsafeChars: TUnsafeChars = [Ord('"'), Ord(''''), Ord(':'), Ord(';'), Ord('<'), Ord('='), Ord('>'),
      Ord('@'), Ord('['), Ord(']'), Ord('^'), Ord('`'), Ord('{'), Ord('}'), Ord('|'), Ord('/'), Ord('\'), Ord('?'), Ord('#')];
    const PathUnsafeChars: TUnsafeChars = [Ord('"'), Ord('<'), Ord('>'), Ord('^'), Ord('`'), Ord('{'), Ord('}'), Ord('|'),
      Ord('/'), Ord('\'), Ord('?'), Ord('#'), Ord('+')];
    const QueryUnsafeChars: TUnsafeChars = [Ord('"'), Ord(''''), Ord('<'), Ord('>'), Ord('#')];

URL编码注意事项(以下抄录自“高勇三层Rest服务器产品”):
        URL编码规则:
        签名验证时,要求对字符串中除了“-”、“_”、“.”之外的所有非字母数字字符都要:
                替换成百分号(%)后跟两位大写的十六进制数:十六进制数中字母必须为大写。

        注意事项:
        1. 某些系统方法,例如.NET系统方法HttpUtility.UrlEncode会将‘=’编码成‘%3d’,
                而不是将:‘=’编码成%3D,导致加密签名通不过验证,请开发者注意检查。

        2.Java 1.3和早期版本中,调用java.net.URLEncoder下的方法进行URL编码时,
                某些特殊字符并不会被编码,例如星号(*)。
                由于URL编码规则中规定了星号(*)必须编码,因此在请求字符串中含星号(*)的情况下,
                如果使用了上述方法,会导致生成的签名不能通过验证。
                因此,如果参数值中含有* ,在使用类java.net.URLEncoder下的方法进行编码后,
                需开发人员手动将星号字符:“*”替换为“%2A”,否则将导致加密签名一直通不过验证,请开发者注意检查。

        3. 某些语言的urlencode方法会把“空格”编码为“+”,实际上应该编码为“%20”。
                这也将生成错误的签名,导致签名通不过验证。
                请开发者注意检查,手动将“+”替换为“%20”
                在PHP中,推荐用rawurlencode方法进行URL编码。

1.1.4、关于TNetEncoding其它可用的转化函数

//关于TNetEncoding其它可用的转化函数:
  TNetEncoding = class
  public
    function Decode(const Input, Output: TStream): Integer; overload;
    function Decode(const Input: array of Byte): TBytes; overload;
    function Decode(const Input: string): string; overload;
    function Encode(const Input, Output: TStream): Integer; overload;
    function Encode(const Input: array of Byte): TBytes; overload;
    function Encode(const Input: string): string; overload;
    function DecodeStringToBytes(const Input: string): TBytes;
    function EncodeBytesToString(const Input: array of Byte): string; overload;
    function EncodeBytesToString(const Input: Pointer; Size: Integer): string; overload;
    class property Base64: TNetEncoding read GetBase64Encoding;
    class property HTML: TNetEncoding read GetHTMLEncoding;
    class property URL: TURLEncoding read GetURLEncoding;
  end;

1.2、Web.HTTPApp.pas

function HTTPDecode(const AStr: string): string; inline; deprecated 'Use TNetEncoding.URL.Decode';
function HTTPEncode(const AStr: string): string; inline; deprecated 'Use TNetEncoding.URL.Encode';
function HTMLEncode(const AStr: string): string; inline; deprecated 'Use TNetEncoding.HTML.Encode';
function HTMLDecode(const AStr: string): string; inline; deprecated 'Use TNetEncoding.HTML.Decode';

        Delphi 10.3后过时了:分别推荐使用上述1.1.3、TNetEncoding.URL格式和1.1.2、TNetEncoding.HTML格式。

1.3、IdStrings.pas

        源码在$(Delphi)\source\Indy10\Protocols下

{对表示预定义字符的字符进行编码和解码
HTML4的实体。}

{处理&<>“字符}
function  StrHtmlEncode (const AStr: String): String;
function  StrHtmlDecode (const AStr: String): String;

{处理&<>"'字符}
function StrXHtmlEncode(const ASource: String): String;
function StrXHtmlDecode(const ASource: String): String;

 1.4、关于网页html乱码

//uses System.pas;
{  //:关于字符串的定义:
  _RawByteStr = RawByteString;
  {$IFDEF NEXTGEN}
    UTF8String = type _AnsiString(65001);
    RawByteString = type _AnsiString($ffff);  //:$ffff=  65535
    {$NODEFINE UTF8String}
    {$NODEFINE RawByteString}
  {$ELSEIF Defined(LINUX64) or Defined(OSX64) or Defined(ANDROID)}
    UTF8String = type AnsiString(65001);
    RawByteString = type AnsiString($ffff);  //:$ffff=  65535
    {$NODEFINE UTF8String}
    {$NODEFINE RawByteString}
  {$ELSE}
    UTF8String = type AnsiString(65001);
    RawByteString = type AnsiString($ffff);  //:$ffff=  65535
  {$ENDIF}
    PUTF8String = ^UTF8String;
    PRawByteString = ^RawByteString;
  {$IF Defined(NEXTGEN) or Defined(LINUX64) or Defined(OSX64) or Defined(ANDROID)}
    {$NODEFINE PUTF8String}
    {$NODEFINE PRawByteString}
  {$ENDIF NEXTGEN or LINUX64 or OSX64 or ANDROID}

  function UTF8ToWideString(const S: _RawByteStr): _WideStr; inline;
  function UTF8ToString(const S: _RawByteStr): string; inline; overload;
}

//网页Html的代码用这个函数转化一下,就不乱码啦:
function HtmlDecode(AHtml: string):string;  
begin  
  {$IFDEF UNICODE}  
     Result:= AHtml;  
  {$ELSE}  
     Result:= UTF8ToString(AHtml);  
  {$ENDIF}  
end;  

//网页Html的代码用这个函数转化一下,就不乱码啦:
function HtmlDecode(AHtml: string):string;  
begin  
  {$IFDEF UNICODE}  
     Result:= AHtml;  
  {$ELSE}  
     Result:= UTF8ToString(AHtml);  
  {$ENDIF}  
end;  

二、进制转化

2.1、16进制string转10进制整数int

function HexStrToInt(AHexStr :string):Integer;
begin
  Result:= StrToInt('$'+UpperCase(LHexStr));
end;

2.2、10进制整数int转16进制string

function IntToHexStr(AInt :Integer):string;
var
  LInt: Integer;
  LHexStr: string;
begin
  Result:= Format( '%.2x' ,[AInt] );
end;

2.3、16进制和2进制互转

//uses system.class.pas;

procedure BinToHex(const Buffer: TBytes; BufOffset: Integer;
  var Text: TBytes; TextOffset: Integer; Count: Integer); overload;

function HexToBin(const Text: PChar; TextOffset: Integer;
  var Buffer: TBytes; BufOffset: Integer; Count: Integer): Integer; overload;

        用法函数:

//16进制字符串转2进制字符串
function HexStrToBinStr(AHexStr: string):string;
var
  LResult : WideString;
begin
  SetLength(LResult , Length(AHexStr) div 4);
  HexToBin(PWideChar(AHexStr), LResult [1], Length(AHexStr) div SizeOf(Char));
  Result:= LResult ;
end;


//2进制字符串转16进制字符串
function BinStrToHexStr(ABinStr: string):string;
var
  LResult : String;
begin
  SetLength(LResult , Length(ABinStr) * 4);
  BinToHex(ABinStr[1], PWideChar(LResult), Length(ABinStr) * SizeOf(Char));
  Result:= LResult ;
end;

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/109992895