2015-05-04 139 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; 

,这应该没有任何特殊的设备或部件的工作。