首先过程是这样的,我在JAVA中写了一个servlet,通过servlet将oracle中blob字段中的excel文件取出并且转换为二进制流,通过JAVA的base64类将byte数组转换为字符串,通过xml发送到delphi端,delphi端接收到这个xml文件后,需要对这个字符串进行解析重新转变成base64的byte数组。可是我现在的问题主要是卡在了delphi端,没有一个比较好的实现这种形式的base64算法。我这里有一个,可是不知道能不能使用。看不太懂,我把从xml中得到的字符串放到decode中,可是得不到byte数组。function Decode(const S: AnsiString): AnsiString;
const
  Map: array[Char] of Byte = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
    54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
    3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
    20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30,
    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
    46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0);
var
  I: LongInt;
begin
  case Length(S) of
    2: 
      begin
        I := Map[S[1]] + (Map[S[2]] shl 6);
        SetLength(Result, 1);
        Move(I, Result[1], Length(Result))
      end;
    3: 
      begin
        I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12);
        SetLength(Result, 2);
        Move(I, Result[1], Length(Result))
      end;
    4: 
      begin
        I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) +
          (Map[S[4]] shl 18);
        SetLength(Result, 3);
        Move(I, Result[1], Length(Result))
      end
  end
end;

解决方案 »

  1.   

    不要去case Length,老老实实地转,Base64文本当中允许有换行符等。
      

  2.   

    我想知道的是,在delphi中如何使用base64算法,我还不知道。
    还有就是在java中的base64算法和delphi中的base64算法,是不是一样的。
      

  3.   

    base64算法是一样的,关键是码表问题,只有码表一致才可以正确解出来。
      

  4.   

    Delphi里面有一个TIdDecoderMIME(Indy Misc面板),用它来解就可以了。
      

  5.   

    TIdDecoderMIME 这个东东如何用,我只想把一个xml中的某个节点值进行decode,这样可以吗?
      

  6.   

    你先取Base64串,再调用它不就行了吗?这也要问?!
      

  7.   

    IdDecoderMIME.DecodeString("你加密后的字符串");
      

  8.   

    IdDecoderMIME这个根本不能用,会显示Uneven size in DecodeToStream这个错,
      

  9.   

    是你自己不会用,不是不能用。先搞清楚你传入的内容是否准确。通常XML档当中直接写
    BASE64:***
    这个"base64:"头要去掉。
      

  10.   

    我真的不太会delphi,现在急用,你能不能把话说清楚一些啊,教我一下啊。
      

  11.   

    AAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAA 我的代码是这种。没有base64头啊
      

  12.   

    这不是base64.发一个完整的串,以及原始内容来看看。
      

  13.   

    public  String toBinaryData(Object obj) {
    oracle.sql.BLOB blob = (oracle.sql.BLOB)obj;
    String dataText = "";
    int i = 0;
    try {
    InputStream sr = blob.getBinaryStream();
    FileOutputStream fos = new FileOutputStream("c:/dddd.txt");
    /*
    int data = sr.read();  
      while(data != -1){  
          binStr += String.valueOf(data);
              fos.write(data);  
              data = sr.read();  
      }*/
     int buf = (int)blob.length();
     byte[] blobByte = new byte[buf];
     while ((i = sr.read(blobByte))!= -1) {
     fos.write(blobByte, 0, i);
     }
    dataText = Base64.encodeBytes(blobByte); //用base64位算法将byte二进制转换成字符串
    fos.close();
    sr.close();
    } catch(Exception e) {
    e.printStackTrace();

    return dataText;这是我JAVA中写的程序,
    在JAVA中,我是把二进制数组转换成base64.然后发送到delphi那么在delphi中,我是这样的。
     f := TFileStream.Create('d:/abcd.xls',fmCreate);
        node := xmlNodeList.Get(0);
        tempValue := node.ChildNodes.FindNode('TEMPLATE_FILE');
        str := DecodeString(tempValue.Text);
        //showmessage(inttostr(length(str)));
             SetLength(ByteArray, Length(str));
          for   i   :=   1   to   Length(str)   do   
          begin   
              byteArray[i-1]:=Ord(str[i]);
          end;
          f.Write(byteArray,length(byteArray));可是无法使用,这可怎么办呀。
    我一直也调不通。
      

  14.   

    ‘AAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAA’这可以解出来,只不过是一些二进制数据。不是文本,建议你找一段可识别的文本,先用java转base64,然后试着解码,如果没有问题,再把相应的base64串和文本发上来。另外请告诉我你的Delphi版本,旧版的TIdDecoderMIME有没问题我不是太清楚。
      

  15.   

    下面是我的文章,供参考:http://blog.csdn.net/maozefa/archive/2007/06/14/1653020.aspx
      

  16.   

    function DecodeBase64(Encoded: String):String;
    const 
      Map: array[Char] of Byte = (
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,
         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0);
    var
      I6,I8: Cardinal;
      P,P1: PChar;
      I,Count:Integer;
    begin
      I := Length(Encoded);
      SetLength(result,I div 4 * 3);
      P1 := PChar(Result);
      Count := 0;
      P := PChar(Encoded);
      while I>0 do
        begin
          if I<4 then break;
          I6 := Map[P^];
          Inc(P);
          I6 := (I6 shl 6) + Map[P^];
          Inc(P);
          if P^ = '=' then Dec(Count);
          
          I6 := (I6 shl 6) + Map[P^];
          Inc(P);
          if P^ = '=' then Dec(Count);      I6 := (I6 shl 6) + Map[P^];
          Inc(P);      P1^ := Chr(I6 shr 16);
          Inc(P1);
          Inc(Count);
          P1^ := Chr((I6 shr 8) and $ff);
          Inc(P1);
          Inc(Count);
          P1^ := Chr(I6 and $ff);
          Inc(P1);
          Inc(Count);
          Dec(I,4);
        end;
      SetLength(Result, Count);
    end;
      

  17.   

    ......
    type
    TBytes = array of Byte;
    function DecodeBase64(Encoded: String):TBytes;
    const 
      Map: array[Char] of Byte = (
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,
         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0);
    var
      I6,I8: Cardinal;
      P,P1: PChar;
      I,Count:Integer;
    begin
      I := Length(Encoded);
      SetLength(result,I div 4 * 3);
      P1 := PChar(Result);
      Count := 0;
      P := PChar(Encoded);
      while I>0 do
        begin
          if I<4 then break;
          I6 := Map[P^];
          Inc(P);
          I6 := (I6 shl 6) + Map[P^];
          Inc(P);
          if P^ = '=' then Dec(Count);
          
          I6 := (I6 shl 6) + Map[P^];
          Inc(P);
          if P^ = '=' then Dec(Count);      I6 := (I6 shl 6) + Map[P^];
          Inc(P);      P1^ := Chr(I6 shr 16);
          Inc(P1);
          Inc(Count);
          P1^ := Chr((I6 shr 8) and $ff);
          Inc(P1);
          Inc(Count);
          P1^ := Chr(I6 and $ff);
          Inc(P1);
          Inc(Count);
          Dec(I,4);
        end;
      SetLength(Result, Count);
    end;
      

  18.   

    type
    TBytes = array of Byte;
    function DecodeBase64(Encoded: String):TBytes;
    const 
      Map: array[Char] of Byte = (
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,
         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0);
    var
      I6,I8: Cardinal;
      P,P1: PChar;
      I,Count:Integer;
    begin
      I := Length(Encoded);
      SetLength(result,I div 4 * 3);
      P1 := PChar(Result);
      Count := 0;
      P := PChar(Encoded);
      while I>0 do
        begin
          if I<4 then break;
          while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
          if I<4 then break;
          I6 := Map[P^];
          Inc(P);
          while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
          if I<3 then break;
          I6 := (I6 shl 6) + Map[P^];
          Inc(P);
          while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
          if I<2 then break;
          if P^ = '=' then Dec(Count);
          
          I6 := (I6 shl 6) + Map[P^];
          Inc(P);
          while(P^ in [#$20,#13,#10]) do begin Inc(P);dec(I); end;
          if I<1 then break;
          if P^ = '=' then Dec(Count);      I6 := (I6 shl 6) + Map[P^];
          Inc(P);      P1^ := Chr(I6 shr 16);
          Inc(P1);
          Inc(Count);
          P1^ := Chr((I6 shr 8) and $ff);
          Inc(P1);
          Inc(Count);
          P1^ := Chr(I6 and $ff);
          Inc(P1);
          Inc(Count);
          Dec(I,4);
        end;
      SetLength(Result, Count);
    end;function WriteToFile(FileName: String;Data:PChar;Length:DWORD): DWORD;
    var
      FFileHandle:THandle;
      BytesToWrite,WroteSize:DWORD;
      Buffer:PChar;
    begin
      Result:=0;    FFileHandle:=CreateFile(PChar(LocalExpandFileName(FileName)),
                                GENERIC_READ or GENERIC_WRITE,
                                FILE_SHARE_READ,
                                nil,
                                OPEN_ALWAYS,//CREATE_NEW
                                FILE_ATTRIBUTE_NORMAL,
                                0);
        if FFileHandle=INVALID_HANDLE_VALUE then
          begin
            Result:=GetLastError;
            Exit;
          end;
        try
          if GetLastError=ERROR_ALREADY_EXISTS then
            begin
              if SetFilePointer(FFileHandle,0,nil,FILE_END)=INVALID_SET_FILE_POINTER then
                begin
                  Result:=GetLastError;
                end
              else
                SetLastError(0);
            end;
          Buffer := Data;
          BytesToWrite := Length;
          while BytesToWrite>0 do
            begin
              WroteSize:=0;
              if Not WriteFile(FFileHandle,Buffer^,BytesToWrite,WroteSize,nil) then
                begin
                  Result:=GetLastError;
                  Exit;
                end;
              Buffer:=Pointer(DWORD(Buffer)+WroteSize);
              Dec(BytesToWrite,WroteSize);
            end;
        finally
          CloseHandle(FFileHandle);
        end;end;var
      Bytes :TBytes;
      Src: String;
    begin
      Bytes := DecodeBase64(Src);
      WriteToFile('c:\aaa.xls',PChar(Bytes),Length(Bytes));
      SetLength(Bytes,0);
      Bytes := Nil;
    end;