• base64 d2010版


    代码
    {*******************************************************}
    {                                                       }
    {            Delphi Visual Component Library            }
    {                                                       }
    { Copyright(c) 1995-2010 Embarcadero Technologies, Inc. }
    {                                                       }
    {*******************************************************}

    unit EncdDecd;

    interface

    uses Classes, SysUtils;

    procedure EncodeStream(Input, Output: TStream);
    procedure DecodeStream(Input, Output: TStream);
    function  EncodeString(const Input: string): string;
    function  DecodeString(const Input: string): string;

    function  DecodeBase64(const Input: AnsiString): TBytes;
    function  EncodeBase64(const Input: Pointer; Size: Integer): AnsiString;

    implementation

    uses RTLConsts;

    const
      EncodeTable: 
    array[0..63of AnsiChar =
        AnsiString(
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'+
        AnsiString(
    'abcdefghijklmnopqrstuvwxyz'+
        AnsiString(
    '0123456789+/');

      DecodeTable: 
    array[#0..#127of Integer = (
        Byte(
    '='), 646464646464646464646464646464,
               
    64646464646464646464646464646464,
               
    64646464646464646464646264646463,
               
    52535455565758596061646464646464,
               
    64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  91011121314,
               
    15161718192021222324256464646464,
               
    64262728293031323334353637383940,
               
    41424344454647484950516464646464);

    type
      PPacket 
    = ^TPacket;
      TPacket 
    = packed record
        
    case Integer of
          
    0: (b0, b1, b2, b3: Byte);
          
    1: (i: Integer);
          
    2: (a: array[0..3of Byte);
          
    3: (c: array[0..3of AnsiChar);
      
    end;

      TPointerStream 
    = class(TCustomMemoryStream)
      
    public
        
    constructor Create(P: Pointer; Size: Integer);
        
    function Write(const Buffer; Count: Longint): Longint; override;
      
    end;

    procedure EncodePacket(const Packet: TPacket; NumChars: Integer; OutBuf: PAnsiChar);
    begin
      OutBuf[
    0] := EnCodeTable[Packet.a[0shr 2];
      OutBuf[
    1] := EnCodeTable[((Packet.a[0shl 4or (Packet.a[1shr 4)) and $0000003f];
      
    if NumChars < 2 then
        OutBuf[
    2] := '='
      
    else OutBuf[2] := EnCodeTable[((Packet.a[1shl 2or (Packet.a[2shr 6)) and $0000003f];
      
    if NumChars < 3 then
        OutBuf[
    3] := '='
      
    else OutBuf[3] := EnCodeTable[Packet.a[2and $0000003f];
    end;

    function DecodePacket(InBuf: PAnsiChar; var nChars: Integer): TPacket;
    begin
      Result.a[
    0] := (DecodeTable[InBuf[0]] shl 2or
        (DecodeTable[InBuf[
    1]] shr 4);
      NChars :
    = 1;
      
    if InBuf[2<> '=' then
      
    begin
        Inc(NChars);
        Result.a[
    1] := Byte((DecodeTable[InBuf[1]] shl 4or (DecodeTable[InBuf[2]] shr 2));
      
    end;
      
    if InBuf[3<> '=' then
      
    begin
        Inc(NChars);
        Result.a[
    2] := Byte((DecodeTable[InBuf[2]] shl 6or DecodeTable[InBuf[3]]);
      
    end;
    end;

    procedure EncodeStream(Input, Output: TStream);
    type
      PInteger 
    = ^Integer;
    var
      InBuf: 
    array[0..509of Byte;
      OutBuf: 
    array[0..1023of AnsiChar;
      BufPtr: PAnsiChar;
      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..75of AnsiChar;
      OutBuf: 
    array[0..60of Byte;
      InBufPtr, OutBufPtr: PAnsiChar;
      I, J, K, BytesRead: Integer;
      Packet: TPacket;

      
    procedure SkipWhite;
      
    var
        C: AnsiChar;
        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 :
    = ReadInput;
        InBufPtr :
    = InBuf;
        OutBufPtr :
    = @OutBuf;
        I :
    = 0;
        
    while I < BytesRead do
        
    begin
          Packet :
    = DecodePacket(InBufPtr, J);
          K :
    = 0;
          
    while J > 0 do
          
    begin
            OutBufPtr^ :
    = AnsiChar(Packet.a[K]);
            Inc(OutBufPtr);
            Dec(J);
            Inc(K);
          
    end;
          Inc(InBufPtr, 
    4);
          Inc(I, 
    4);
        
    end;
        Output.Write(OutBuf, OutBufPtr 
    - PAnsiChar(@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;

    constructor TPointerStream.Create(P: Pointer; Size: Integer);
    begin
      SetPointer(P, Size);
    end;

    function TPointerStream.Write(const Buffer; Count: Longint): Longint;
    var
      Pos, EndPos, Size: Longint;
      Mem: Pointer;
    begin
      Pos :
    = Self.Position;

      
    if (Pos >= 0and (Count > 0then
      
    begin
        EndPos :
    = Pos + Count;
        Size:
    = Self.Size;
        
    if EndPos > Size then
          
    raise EStreamError.CreateRes(@SMemoryStreamError);

        Mem :
    = Self.Memory;
        System.Move(Buffer, Pointer(Longint(Mem) 
    + Pos)^, Count);
        Self.Position :
    = Pos;
        Result :
    = Count;
        Exit;
      
    end;
      Result :
    = 0;
    end;

    function DecodeBase64(const Input: AnsiString): TBytes;
    var
      InStr: TPointerStream;
      OutStr: TBytesStream;
      Len: Integer;
    begin
      InStr :
    = TPointerStream.Create(PAnsiChar(Input), Length(Input));
      
    try
        OutStr :
    = TBytesStream.Create;
        
    try
          DecodeStream(InStr, OutStr);
          Result :
    = OutStr.Bytes;
          Len :
    = OutStr.Size;
        
    finally
          OutStr.Free;
        
    end;
      
    finally
        InStr.Free;
      
    end;
      SetLength(Result, Len);
    end;

    function EncodeBase64(const Input: Pointer; Size: Integer): AnsiString;
    var
      InStr: TPointerStream;
      OutStr: TBytesStream;
    begin  
      InStr :
    = TPointerStream.Create(Input, Size);
      
    try
        OutStr :
    = TBytesStream.Create;
        
    try
          EncodeStream(InStr, OutStr);
          SetString(Result, PAnsiChar(OutStr.Memory), OutStr.Size);
        
    finally
          OutStr.Free;
        
    end;
      
    finally
        InStr.Free;
      
    end;
    end;


    end.
  • 相关阅读:
    python求3的倍数与和
    linux内核优化参数
    ssh 调优参数
    mysql xtarbackup备份脚本
    mysql全库备份数据库脚本
    python json模块
    python函数介绍
    字典常用操作
    python常用字符串操作
    最好的10本适用于初学者阅读的javaScript和jQuery书籍
  • 原文地址:https://www.cnblogs.com/jxgxy/p/1639084.html
Copyright © 2020-2023  润新知