Delphi 自带了 Base64 编解码的单元

Delphi 自带了 Base64 编解码的单元,叫 EncdDecd,
这名字很拗口而且不直观,估计这是一直很少人关注和知道的原因。  
这个单元提供两套四个公开函数:  对流的编解码: procedure EncodeStream(Input, Output: TStream); 
// 编码 procedure DecodeStream(Input, Output: TStream); // 解码  
// 对字符串的编解码: 
function  EncodeString(const Input: string): string; 
// 编码 
function  DecodeString(const Input: string): string; 

// 解码  这几个函数在帮助中没有。应该不算是标准库中的函数。  

{********************************************************}  {                                                        }  {          Borland Delphi Visual Component Library       }  {                                                        }  { Copyright (c) 2000, 2001 Borland Software Corporation  }  {                                                        }  {********************************************************}  unit EncdDecd;    { Have string use stream encoding since that logic wraps properly }        interface    uses Classes;    procedure EncodeStream(Input, Output: TStream);  procedure DecodeStream(Input, Output: TStream);  function  EncodeString(const Input: string): string;  function  DecodeString(const Input: string): string;    implementation    const    EncodeTable: array[0..63] of Char =      'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +      'abcdefghijklmnopqrstuvwxyz' +      '0123456789+/';      DecodeTable: array[#0..#127] of Integer = (      Byte('='), 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,      64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,      64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,      52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,      64,  0,  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, 64, 64, 64, 64, 64,      64, 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, 64, 64, 64, 64, 64);    type    PPacket = ^TPacket;    TPacket = packed record      case Integer of        0: (b0, b1, b2, b3: Byte);        1: (i: Integer);        2: (a: array[0..3] of Byte);        3: (c: array[0..3] of Char);    end;    procedure EncodePacket(const Packet: TPacket; NumChars: Integer; OutBuf: PChar);  begin    OutBuf[0] := EnCodeTable[Packet.a[0] shr 2];    OutBuf[1] := EnCodeTable[((Packet.a[0] shl 4) or (Packet.a[1] shr 4)) and $0000003f];    if NumChars < 2 then      OutBuf[2] := '='    else OutBuf[2] := EnCodeTable[((Packet.a[1] shl 2) or (Packet.a[2] shr 6)) and $0000003f];    if NumChars < 3 then      OutBuf[3] := '='    else OutBuf[3] := EnCodeTable[Packet.a[2] and $0000003f];  end;    function DecodePacket(InBuf: PChar; var nChars: Integer): TPacket;  begin    Result.a[0] := (DecodeTable[InBuf[0]] shl 2) or      (DecodeTable[InBuf[1]] shr 4);    NChars := 1;    if InBuf[2] <> '=' then    begin      Inc(NChars);      Result.a[1] := Byte((DecodeTable[InBuf[1]] shl 4) or (DecodeTable[InBuf[2]] shr 2));    end;    if InBuf[3] <> '=' then    begin      Inc(NChars);      Result.a[2] := Byte((DecodeTable[InBuf[2]] shl 6) or DecodeTable[InBuf[3]]);    end;  end;    procedure EncodeStream(Input, Output: TStream);  type    PInteger = ^Integer;  var    InBuf: array[0..509] of Byte;    OutBuf: array[0..1023] of Char;    BufPtr: PChar;    I, J, K, BytesRead: Integer;    Packet: TPacket;  begin    K := 0;    repeat      BytesRead := Input.Read(InBuf, SizeOf(InBuf));      I := 0;      BufPtr := OutBuf;      while I < BytesRead do      begin        if BytesRead - I < 3 then          J := BytesRead - I        else J := 3;        Packet.i := 0;        Packet.b0 := InBuf[I];        if J > 1 then          Packet.b1 := InBuf[I + 1];        if J > 2 then          Packet.b2 := InBuf[I + 2];        EncodePacket(Packet, J, BufPtr);        Inc(I, 3);        Inc(BufPtr, 4);        Inc(K, 4);        if K > 75 then        begin          BufPtr[0] := #$0D;          BufPtr[1] := #$0A;          Inc(BufPtr, 2);          K := 0;        end;      end;      Output.Write(Outbuf, BufPtr - PChar(@OutBuf));    until BytesRead = 0;  end;    procedure DecodeStream(Input, Output: TStream);  var    InBuf: array[0..75] of Char;    OutBuf: array[0..60] of Byte;    InBufPtr, OutBufPtr: PChar;    I, J, K, BytesRead: Integer;    Packet: TPacket;      procedure SkipWhite;    var      C: Char;      NumRead: Integer;    begin      while True do      begin        NumRead := Input.Read(C, 1);        if NumRead = 1 then        begin          if C in ['0'..'9','A'..'Z','a'..'z','+','/','='] then          begin            Input.Position := Input.Position - 1;            Break;          end;        end else Break;      end;    end;      function ReadInput: Integer;    var      WhiteFound, EndReached : Boolean;      CntRead, Idx, IdxEnd: Integer;    begin      IdxEnd:= 0;      repeat        WhiteFound := False;        CntRead := Input.Read(InBuf[IdxEnd], (SizeOf(InBuf)-IdxEnd));        EndReached := CntRead < (SizeOf(InBuf)-IdxEnd);        Idx := IdxEnd;        IdxEnd := CntRead + IdxEnd;        while (Idx < IdxEnd) do        begin          if not (InBuf[Idx] in ['0'..'9','A'..'Z','a'..'z','+','/','=']) then          begin            Dec(IdxEnd);            if Idx < IdxEnd then              Move(InBuf[Idx+1], InBuf[Idx], IdxEnd-Idx);            WhiteFound := True;          end          else            Inc(Idx);        end;      until (not WhiteFound) or (EndReached);      Result := IdxEnd;    end;    begin    repeat      SkipWhite;      {      BytesRead := Input.Read(InBuf, SizeOf(InBuf));      }      BytesRead := ReadInput;      InBufPtr := InBuf;      OutBufPtr := @OutBuf;      I := 0;      while I < BytesRead do      begin        Packet := DecodePacket(InBufPtr, J);        K := 0;        while J > 0 do        begin          OutBufPtr^ := Char(Packet.a[K]);          Inc(OutBufPtr);          Dec(J);          Inc(K);        end;        Inc(InBufPtr, 4);        Inc(I, 4);      end;      Output.Write(OutBuf, OutBufPtr - PChar(@OutBuf));    until BytesRead = 0;  end;    function EncodeString(const Input: string): string;    var    InStr, OutStr: TStringStream;  begin    InStr := TStringStream.Create(Input);    try      OutStr := TStringStream.Create('');      try        EncodeStream(InStr, OutStr);        Result := OutStr.DataString;      finally        OutStr.Free;      end;    finally      InStr.Free;    end;  end;     function DecodeString(const Input: string): string;    var    InStr, OutStr: TStringStream;  begin    InStr := TStringStream.Create(Input);    try      OutStr := TStringStream.Create('');      try        DecodeStream(InStr, OutStr);        Result := OutStr.DataString;      finally        OutStr.Free;      end;    finally      InStr.Free;    end;  end;   end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值