关于使用delphi中Base64的问题,请大家帮我分析一下。

longyun6323 2008-05-29 09:11:07
首先过程是这样的,我在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;
...全文
1116 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
yejinson 2009-05-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 unsigned 的回复:]
Delphi里面有一个TIdDecoderMIME(Indy Misc面板),用它来解就可以了。
[/Quote]
用这个可以
僵哥 2009-05-13
  • 打赏
  • 举报
回复
我挖
僵哥 2008-05-29
  • 打赏
  • 举报
回复
你先取Base64串,再调用它不就行了吗?这也要问?!
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
TIdDecoderMIME 这个东东如何用,我只想把一个xml中的某个节点值进行decode,这样可以吗?
僵哥 2008-05-29
  • 打赏
  • 举报
回复
Delphi里面有一个TIdDecoderMIME(Indy Misc面板),用它来解就可以了。
僵哥 2008-05-29
  • 打赏
  • 举报
回复
base64算法是一样的,关键是码表问题,只有码表一致才可以正确解出来。
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
我想知道的是,在delphi中如何使用base64算法,我还不知道。
还有就是在java中的base64算法和delphi中的base64算法,是不是一样的。
僵哥 2008-05-29
  • 打赏
  • 举报
回复
不要去case Length,老老实实地转,Base64文本当中允许有换行符等。
僵哥 2008-05-29
  • 打赏
  • 举报
回复
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;
僵哥 2008-05-29
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 longyun6323 的回复:]
你的这种方法,最后只是返回一个字符串啊,而不是一个字节数组啊。
[/Quote]
......
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;
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
你的这种方法,最后只是返回一个字符串啊,而不是一个字节数组啊。
僵哥 2008-05-29
  • 打赏
  • 举报
回复
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;
阿发伯 2008-05-29
  • 打赏
  • 举报
回复
僵哥 2008-05-29
  • 打赏
  • 举报
回复
‘AAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAA’这可以解出来,只不过是一些二进制数据。不是文本,建议你找一段可识别的文本,先用java转base64,然后试着解码,如果没有问题,再把相应的base64串和文本发上来。

另外请告诉我你的Delphi版本,旧版的TIdDecoderMIME有没问题我不是太清楚。
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
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));

可是无法使用,这可怎么办呀。
我一直也调不通。
僵哥 2008-05-29
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 longyun6323 的回复:]
AAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAA 我的代码是这种。没有base64头啊
[/Quote]
这不是base64.发一个完整的串,以及原始内容来看看。
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
AAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAA 我的代码是这种。没有base64头啊
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
我真的不太会delphi,现在急用,你能不能把话说清楚一些啊,教我一下啊。
僵哥 2008-05-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 longyun6323 的回复:]
IdDecoderMIME这个根本不能用,会显示Uneven size in DecodeToStream这个错,
[/Quote]
是你自己不会用,不是不能用。先搞清楚你传入的内容是否准确。通常XML档当中直接写
BASE64:***
这个"base64:"头要去掉。
longyun6323 2008-05-29
  • 打赏
  • 举报
回复
IdDecoderMIME这个根本不能用,会显示Uneven size in DecodeToStream这个错,
加载更多回复(1)

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧