2015-05-04 327 views
2

我必須在舊的Delphi 2007上將字節數組編碼爲base64字符串(並解碼此字符串)。 我該怎麼辦?使用delphi 2007編碼base64和解碼base64

進一步信息:

我試過突觸(如這裏Binary to Base64 (Delphi)建議)。

+0

Base64是一種標準編碼,無論語言或版本如何。這意味着它的編碼或解碼方式有問題。我們可以看到你的代碼嗎? –

+1

你可以使用Indy嘗試'TIdDecoderMIME'類。 – RRUZ

+1

和'TIdEncoderMIME' –

回答

9

Indy附帶Delphi,並且具有用於處理base64的TIdEncoderMIMETIdDecoderMIME類。例如:

uses 
    ..., IdCoder, IdCoderMIME; 

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

還有用於編碼/解碼的方法和String數據TStream爲好。

更新:另外,如果你的版本沒有在上面顯示的class方法:

// 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; 
+0

它進一步德爾福版本效果很好!感謝您的建議和示例,我會盡快在Delphi 2007上進行檢查,但我認爲它也適用於舊的IDE。 – Hwau

+1

@Hwau:您可以將Indy升級到最新版本,即使是舊的Delphi's – whosrdaddy

+0

不幸的是,EncodeBytes和DecodeBytes函數未使用Delphi2007聲明。我寧願不手動升級indy,有沒有另一種方法? – Hwau

2

相反,你的問題說出什麼,該EncdDecd單元包括在2007年德爾福你可以簡單地使用它。

0

這裏去EncodeToBase64:

uses 
classes, sysutils; 

function EncodeToBase64(var Buffer: TBytes): Longint; 
const 
    EncodingTable: PChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'; 
var 
    WriteBuf: array[0..3] of Byte; 
    Buf: array[0..2] of Byte; 
    Dest: TMemoryStream; 
    i, j, Count: Integer; 
begin 
    Result := 0; 

    Count := Length(Buffer); 
    j := Count div 3; 

    if j > 0 then 
    begin 
    Dest:= TMemoryStream.Create(); 
    try 
     Dest.Position := 0; 
     for i := 0 to j - 1 do 
     begin 
     Move(Buffer[i * 3], Buf[0], 3); 
     WriteBuf[0] := Ord(EncodingTable[Buf[0] shr 2]); 
     WriteBuf[1] := Ord(EncodingTable[(Buf[0] and 3) shl 4 or (Buf[1] shr 4)]); 
     WriteBuf[2] := Ord(EncodingTable[(Buf[1] and 15) shl 2 or (Buf[2] shr 6)]); 
     WriteBuf[3] := Ord(EncodingTable[Buf[2] and 63]); 
     Dest.Write(WriteBuf, 4); 
     Inc(Result, 4); 
     Dec(Count, 3);  
     end;   

     if Count in [1, 2] then 
     begin   
     Move(Buffer[i * 3], Buf[0], Count); 
     WriteBuf[0] := Ord(EncodingTable[Buf[0] shr 2]); 
     WriteBuf[1] := Ord(EncodingTable[(Buf[0] and 3) shl 4 or (Buf[1] shr 4)]); 
     if Count = 1 then 
      WriteBuf[2] := Ord('=') 
     else           
      WriteBuf[2] := Ord(EncodingTable[(Buf[1] and 15) shl 2 or (Buf[2] shr 6)]); 
     WriteBuf[3] := Ord('='); 
     Dest.Write(WriteBuf, 4); 
     Inc(Result, 4); 
     Dec(Count, Count); 
     end; 

     if Result > 0 then 
     begin 
     SetLength(Buffer, Result); 
     Dest.Position := 0; 
     Dest.Read(Buffer[0], Result); 
     end; 
    finally 
     Dest.Free; 
    end; 
    end; 

end; 

,這應該沒有任何特殊的設備或部件的工作。