因业务需要,调用服务端接口返回的content内容是加密的,加密流程为:BASE64.encode(ZIP 压缩(xml 明文))。其解密流程为:BASE64.decode(ZIP 解压缩(UTF-8转码))
其中的ZIP压缩实际为GZip压缩,两者的压缩方式稍有不同,使用Delphi在解压时就需要不同的方法来处理。
查找了各种资料,最终确定使用zipLibEx的源码包+搜索的一些使用技巧可以解压gZip。因为业务需要,本文也加入了base64解密、utf-8转码的一些操作技巧。
加密文字:
H4sIAAAAAAAEAHWOSw+CMBCE/0rTu7ZAipKUcuARLwW0GumJGERDAjRKov58l8fJxNPOfjPZWR58uha96ufQmN7H1ppiVPeVuTb93cenY7La4kDwQ6zyLFVxGWZSZmkZaRChQlV7GQYf/9po8bHgkS4KNQ/BkzySglFKLeYwl3IyAcA7KahnO97GdUcIKw/PYEEUUpMEACeY6Y5M229mmj3Tj9tojpfJXECWOvLnYfEF5cZJhPAAAAA=
解密明文:
'<?xml version="1.0" encoding="UTF-8"?><RESPONSE_COMMON_DYCOMCS class="RESPONSE_COMMON_ DYCOMCS"><DYXXS><DYXX>……<CWDM>0000</CWDM><CWXX>5omT5Y2w5oiQ5Yqf</CWXX></DYXX></DYXXS></RESPONSE_COMMON_DYCOMCS>
uses Soap.EncdDecd{base64解密使用},ZLibEx{gZip解压使用}
//Gzip解压函数的封装,感谢前辈们的代码
procedure DecompressGZip(AInStream, AOutStream: TStream);
var
pb1, pb2: Byte;
begin
AInStream.Seek(1, 0);
AInStream.Read(pb1, 1);
AInStream.Seek(2, 0);
AInStream.Read(pb2, 1);
AInStream.Position := 0;
AOutStream.Position := 0;
if (pb1 = $8B) and (pb2 = $8) then //$8B和$8判断是否压缩
ZDecompressStream2(AInStream, AOutStream, 47) //调用gzip解压
else
AOutStream.CopyFrom(AInStream, AInStream.Size);
end;
function DecodeGzipUTF8String(Input: PChar; var AOutStr: WideString): Boolean; stdcall;
var
InStr, OutStr: TStringStream;
stream, out_stream: TStringStream;
deStr: string;
begin
Result := False;
//解压方法使用流处理,所以这里都用TStringStream来操作
InStr := TStringStream.create(Input);
stream := TStringStream.Create;
out_stream := TStringStream.Create;
OutStr := TStringStream.create('');
try
DecodeStream(InStr, OutStr);//先base64解密
DecompressGZip(OutStr, stream); //再解压
out_stream := TStringStream.Create('', TEncoding.UTF8);
out_stream.LoadFromStream(stream); //再UTF-8转码
deStr := out_stream.DataString;//读出流数据
AOutStr := deStr;
Result := True;
finally
FreeAndNil(OutStr);
FreeAndNil(InStr);
FreeAndNil(stream);
FreeAndNil(out_stream);
end;
end;
调用方法:
function TForm2.DecodeGZIPUTF8Str(InPut: string): string;
var
DecodeStr: WideString;
begin
Result := '';
DecodeGzipUTF8String(PChar(InPut),DecodeStr);
Result := DecodeStr;
end;