使用 zlib 压缩 Base64 字符串
Compress Base64 string with zlib
我需要通过 TCP 协议从 Windows 向移动设备 iOS 和 Android 发送一个大的 Base64 字符串。
我发送和接收都没有问题,但是字符串太大,大约 24000 个字符,我正在寻找压缩和解压缩这些字符串的方法。
看起来我明白了,最好的方法是使用 Zlib,我发现这些 link Delphi XE and ZLib Problems (II) 其中解释了如何做。
这些函数适用于普通文本字符串,但压缩 base64 字符串会使它们变得更大。
我将发送的一个非常小的字符串的示例是:
cEJNYkpCSThLVEh6QjNFWC9wSGhXQ3lHWUlBcGNURS83TFdDNVUwUURxRnJvZlRVUWd4WEFWcFJBNUZSSE9JRXlsaWgzcEJvTGo5anQwTlEyd1pBTEtVQVlPbXdkKzJ6N3J5ZUd4SmU2bDNBWjFEd3lVZmZTR1FwNXRqWTVFOFd2SHRwakhDOU9JUEZRM00wMWhnU0p3MWxxNFRVdmdEU2pwekhwV2thS0JFNG9WYXRDUHhTdnp4blU5Vis2ZzJQYnRIdllubzhKSFhZeUlpckNtTGtUZHVHOTFncHVUWC9FSTdOK3JEUDBOVzlaTngrcEdxcXhpRWJ1ZXNUMmdxOXpJa0ZEak1ORHBFenFVSTlCdytHTy==
我不知道是否可以压缩这种类型的字符串。我需要帮助。
我使用的函数是这样的:
uses
SysUtils, Classes, ZLib, EncdDecd;
function CompressAndEncodeString(const Str: string): string;
var
Utf8Stream: TStringStream;
Compressed: TMemoryStream;
Base64Stream: TStringStream;
begin
Utf8Stream := TStringStream.Create(Str, TEncoding.UTF8);
try
Compressed := TMemoryStream.Create;
try
ZCompressStream(Utf8Stream, Compressed);
Compressed.Position := 0;
Base64Stream := TStringStream.Create('', TEncoding.ASCII);
try
EncodeStream(Compressed, Base64Stream);
Result := Base64Stream.DataString;
finally
Base64Stream.Free;
end;
finally
Compressed.Free;
end;
finally
Utf8Stream.Free;
end;
end;
function DecodeAndDecompressString(const Str: string): string;
var
Utf8Stream: TStringStream;
Compressed: TMemoryStream;
Base64Stream: TStringStream;
begin
Base64Stream := TStringStream.Create(Str, TEncoding.ASCII);
try
Compressed := TMemoryStream.Create;
try
DecodeStream(Base64Stream, Compressed);
Compressed.Position := 0;
Utf8Stream := TStringStream.Create('', TEncoding.UTF8);
try
ZDecompressStream(Compressed, Utf8Stream);
Result := Utf8Stream.DataString;
finally
Utf8Stream.Free;
end;
finally
Compressed.Free;
end;
finally
Base64Stream.Free;
end;
end;
据我了解,您已完成以下问题:
- 将字符串编码为 UTF-8 字节。
- 使用 zlib 压缩了这些字节。
- Base64 编码压缩字节。
然后您尝试压缩步骤 3 的输出,发现结果并没有变小。这是可以预料的。您已经压缩了数据,并且不能指望进一步尝试压缩它会显着减小大小,尤其是如果您同时使用 base64 编码的话。如果您可以反复压缩数据,并且每次都将其变小,那么最终将一无所有。那显然是不可能的。
我认为你已经做得很好了。您转换为 UTF-8,对于大多数文本,UTF-8 是最 space 有效的 Unicode 编码。如果您使用中文文本,那么使用 UTF-16 会更好。然后你压缩 UTF-8 这也是合理的。最后传输用base64编码,也是合理的。
减少要传输的数据大小的最明显方法是省略 base64 步骤。如果您可以传输在步骤 2 中生成的压缩字节,那么您将传输更少。 Base64 使用 4 个字节编码 3 个字节,因此 base64 编码数据的大小比输入数据大三分之一。
另一种方法可能是使用比 zlib 更好的压缩算法,但同样存在限制。通常更好的压缩是以增加计算时间为代价的。
我需要通过 TCP 协议从 Windows 向移动设备 iOS 和 Android 发送一个大的 Base64 字符串。
我发送和接收都没有问题,但是字符串太大,大约 24000 个字符,我正在寻找压缩和解压缩这些字符串的方法。
看起来我明白了,最好的方法是使用 Zlib,我发现这些 link Delphi XE and ZLib Problems (II) 其中解释了如何做。
这些函数适用于普通文本字符串,但压缩 base64 字符串会使它们变得更大。
我将发送的一个非常小的字符串的示例是:
cEJNYkpCSThLVEh6QjNFWC9wSGhXQ3lHWUlBcGNURS83TFdDNVUwUURxRnJvZlRVUWd4WEFWcFJBNUZSSE9JRXlsaWgzcEJvTGo5anQwTlEyd1pBTEtVQVlPbXdkKzJ6N3J5ZUd4SmU2bDNBWjFEd3lVZmZTR1FwNXRqWTVFOFd2SHRwakhDOU9JUEZRM00wMWhnU0p3MWxxNFRVdmdEU2pwekhwV2thS0JFNG9WYXRDUHhTdnp4blU5Vis2ZzJQYnRIdllubzhKSFhZeUlpckNtTGtUZHVHOTFncHVUWC9FSTdOK3JEUDBOVzlaTngrcEdxcXhpRWJ1ZXNUMmdxOXpJa0ZEak1ORHBFenFVSTlCdytHTy==
我不知道是否可以压缩这种类型的字符串。我需要帮助。
我使用的函数是这样的:
uses
SysUtils, Classes, ZLib, EncdDecd;
function CompressAndEncodeString(const Str: string): string;
var
Utf8Stream: TStringStream;
Compressed: TMemoryStream;
Base64Stream: TStringStream;
begin
Utf8Stream := TStringStream.Create(Str, TEncoding.UTF8);
try
Compressed := TMemoryStream.Create;
try
ZCompressStream(Utf8Stream, Compressed);
Compressed.Position := 0;
Base64Stream := TStringStream.Create('', TEncoding.ASCII);
try
EncodeStream(Compressed, Base64Stream);
Result := Base64Stream.DataString;
finally
Base64Stream.Free;
end;
finally
Compressed.Free;
end;
finally
Utf8Stream.Free;
end;
end;
function DecodeAndDecompressString(const Str: string): string;
var
Utf8Stream: TStringStream;
Compressed: TMemoryStream;
Base64Stream: TStringStream;
begin
Base64Stream := TStringStream.Create(Str, TEncoding.ASCII);
try
Compressed := TMemoryStream.Create;
try
DecodeStream(Base64Stream, Compressed);
Compressed.Position := 0;
Utf8Stream := TStringStream.Create('', TEncoding.UTF8);
try
ZDecompressStream(Compressed, Utf8Stream);
Result := Utf8Stream.DataString;
finally
Utf8Stream.Free;
end;
finally
Compressed.Free;
end;
finally
Base64Stream.Free;
end;
end;
据我了解,您已完成以下问题:
- 将字符串编码为 UTF-8 字节。
- 使用 zlib 压缩了这些字节。
- Base64 编码压缩字节。
然后您尝试压缩步骤 3 的输出,发现结果并没有变小。这是可以预料的。您已经压缩了数据,并且不能指望进一步尝试压缩它会显着减小大小,尤其是如果您同时使用 base64 编码的话。如果您可以反复压缩数据,并且每次都将其变小,那么最终将一无所有。那显然是不可能的。
我认为你已经做得很好了。您转换为 UTF-8,对于大多数文本,UTF-8 是最 space 有效的 Unicode 编码。如果您使用中文文本,那么使用 UTF-16 会更好。然后你压缩 UTF-8 这也是合理的。最后传输用base64编码,也是合理的。
减少要传输的数据大小的最明显方法是省略 base64 步骤。如果您可以传输在步骤 2 中生成的压缩字节,那么您将传输更少。 Base64 使用 4 个字节编码 3 个字节,因此 base64 编码数据的大小比输入数据大三分之一。
另一种方法可能是使用比 zlib 更好的压缩算法,但同样存在限制。通常更好的压缩是以增加计算时间为代价的。