et3*_*al1 0 delphi base64 delphi-6
我正在将二进制文件加载到内存流中,然后对数据进行编码,并将结果作为字符串返回,然后将结果写入另一个内存流,并将其保存到文件中,但是当它保存时文件比原始文件小得多来自400kb的25kb ...大声笑,我很确定这是因为我已达到字符串能够处理的极限.
它肯定地编码它正确保存在新文件中的数据,我解密它并将其与原始文件的开头进行比较.
我知道这是一个非常漫长的方法,并且可能有一些不必要的步骤,因此将其加载到bStream中将是一个非常有效的解决方案.我的问题是我怎样才能将数据返回到bStream而不是让它返回到字符串然后将字符串写入bStream,因为我相信它会解决我的问题,任何其他建议也将受到赞赏.我正在使用Delphi 6.
继承我的代码:
function B64Encode(pInput: pointer; pOutput: pointer; Size: longint): longint;
var
i, iptr, optr: integer;
Input, Output: PByteArray;
begin
Input := PByteArray(pInput);
Output := PByteArray(pOutput);
iptr := 0;
optr := 0;
for i := 1 to (Size div 3) do
begin
Output^[optr + 0] := B64[Input^[iptr] shr 2];
Output^[optr + 1] := B64[((Input^[iptr] and 3) shl 4) + (Input^[iptr + 1] shr 4)];
Output^[optr + 2] := B64[((Input^[iptr + 1] and 15) shl 2) + (Input^[iptr + 2] shr 6)];
Output^[optr + 3] := B64[Input^[iptr + 2] and 63];
Inc(optr, 4);
Inc(iptr, 3);
end;
case (Size mod 3) of
1:
begin
Output^[optr + 0] := B64[Input^[iptr] shr 2];
Output^[optr + 1] := B64[(Input^[iptr] and 3) shl 4];
Output^[optr + 2] := byte('=');
Output^[optr + 3] := byte('=');
end;
2:
begin
Output^[optr + 0] := B64[Input^[iptr] shr 2];
Output^[optr + 1] := B64[((Input^[iptr] and 3) shl 4) + (Input^[iptr + 1] shr 4)];
Output^[optr + 2] := B64[(Input^[iptr + 1] and 15) shl 2];
Output^[optr + 3] := byte('=');
end;
end;
Result := ((Size + 2) div 3) * 4;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
aStream, bStream: TMemoryStream;
strastream: string;
szaStream: integer;
begin
bStream := TMemoryStream.Create;
aStream := TMemoryStream.Create;
aStream.LoadFromFile('C:\file1.exe');
szaStream := (astream.size + 2) div (3 * 4);
SetLength(strastream, szaStream);
B64Encode(astream.Memory, @strastream[1], Length(strastream));
bstream.WriteBuffer(strastream[1], szaStream);
AttachToFile('C:\file2.exe', bStream);
bstream.Free;
aStream.Free;
end;
Run Code Online (Sandbox Code Playgroud)
谢谢.
你的长度计算都是错误的,正如评论中指出的那样.
szaStream := (astream.size + 2) div (3 * 4);
Run Code Online (Sandbox Code Playgroud)
这意味着您的编码流的大小是输入流的1/12.但它需要更大.你的意思是:
szaStream := ((astream.size * 4) div 3) + 2;
Run Code Online (Sandbox Code Playgroud)
我也没有看到在这里使用字符串的意义.您可以直接写入流.
并且,值得重复的是,使用base 64进行编码而不是加密.
在我看来,当Delphi附带一个base 64实现时,自己写这些内容几乎没有意义.如果您使用名称空间,则该单元称为EncdDecd或Soap.EncdDecd.而你唯一需要的功能就是
procedure EncodeStream(Input, Output: TStream);
Run Code Online (Sandbox Code Playgroud)
创建两个文件流,一个用于读取,一个用于写入,并将它们传递给该函数.例如:
procedure EncodeFileBase64(const InFileName, OutFileName:string);
var
Input, Output: TStream;
begin
Input := TFileStream.Create(InFileName, fmOpenRead);
try
Output := TFileStream.Create(InFileName, fmCreate);
try
EncodeStream(Input, Output);
finally
Output.Free;
end;
finally
Input.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
如果你需要反转这个过程,那么你猜对了DecodeStream.
如果性能很重要,那么您可能需要使用缓冲流而不是TFileStream.例如:缓冲文件(用于更快的磁盘访问)
| 归档时间: |
|
| 查看次数: |
533 次 |
| 最近记录: |