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.
原文地址:https://www.cnblogs.com/jxgxy/p/1639084.html