delphiencodingbase64decodingdelphi-2007

Encode base64 and Decode base64 using delphi 2007


I have to encode an array of bytes to a base64 string (and decode this string) on an old Delphi 2007. How could I do?

Further Informations:

I've tried synapse (As suggested here Binary to Base64 (Delphi)).


Solution

  • Indy ships with Delphi, and has TIdEncoderMIME and TIdDecoderMIME classes for handling base64. For example:

    uses
      ..., IdCoder, IdCoderMIME;
    
    var
      Bytes: TIdBytes;
      Base64String: String;
    begin
      //...
      Bytes := ...; // array of bytes
      //...
      Base64String := TIdEncoderMIME.EncodeBytes(Bytes);
      //...
      Bytes := TIdDecoderMIME.DecodeBytes(Base64String);
      //...
    end;
    

    There are also methods for encoding/decoding String and TStream data as well.

    Update: alternatively, if your version does not have the class methods shown above:

    // TBytesStream was added in D2009, so define it manually for D2007
    
    uses
      ..., IdCoder, IdCoderMIME
      {$IF RTLVersion < 20}
      , RTLConsts
      {$IFEND}
      ;
    
    {$IF RTLVersion < 20}
    type
      TBytesStream = class(TMemoryStream)
      private
        FBytes: TBytes;
      protected
        function Realloc(var NewCapacity: Longint): Pointer; override;
      public
        constructor Create(const ABytes: TBytes); overload;
        property Bytes: TBytes read FBytes;
      end;
    
    constructor TBytesStream.Create(const ABytes: TBytes);
    begin
      inherited Create;
      FBytes := ABytes;
      SetPointer(Pointer(FBytes), Length(FBytes));
      FCapacity := FSize;
    end;
    
    const
      MemoryDelta = $2000; // Must be a power of 2
    
    function TBytesStream.Realloc(var NewCapacity: Integer): Pointer;
    begin
      if (NewCapacity > 0) and (NewCapacity <> FSize) then
        NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1);
      Result := Pointer(FBytes);
      if NewCapacity <> FCapacity then
      begin
        SetLength(FBytes, NewCapacity);
        Result := Pointer(FBytes);
        if NewCapacity = 0 then
          Exit;
        if Result = nil then raise EStreamError.CreateRes(@SMemoryStreamError);
      end;
    end;
    {$IFEND}
    
    var
      Bytes: TBytes;
      BStrm: TBytesStream;
      Encoder: TIdEncoderMIME;
      Decoder: TIdDecoderMIME;
      Base64String: String;
    begin
      //...
      Bytes := ...; // array of bytes
      //...
      BStrm := TBytesStream.Create(Bytes);
      try
        Encoder := TIdEncoderMIME.Create;
        try
          Base64String := Encoder.Encode(BStrm);
        finally
          Encoder.Free;
        end;
      finally
        BStrm.Free;
      end;
      //...
      BStrm := TBytesStream.Create;
      try
        Decoder := TIdDecoderMIME.Create;
        try
          Decoder.DecodeBegin(BStrm);
          Decoder.Decode(Base64String);
          Decoder.DecodeEnd;
        finally
          Decoder.Free;
        end;
        Bytes := BStrm.Bytes;
      finally
        BStrm.Free;
      end;
      //...
    end;