使用 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;

据我了解,您已完成以下问题:

  1. 将字符串编码为 UTF-8 字节。
  2. 使用 zlib 压缩了这些字节。
  3. Base64 编码压缩字节。

然后您尝试压缩步骤 3 的输出,发现结果并没有变小。这是可以预料的。您已经压缩了数据,并且不能指望进一步尝试压缩它会显着减小大小,尤其是如果您同时使用 base64 编码的话。如果您可以反复压缩数据,并且每次都将其变小,那么最终将一无所有。那显然是不可能的。

我认为你已经做得很好了。您转换为 UTF-8,对于大多数文本,UTF-8 是最 space 有效的 Unicode 编码。如果您使用中文文本,那么使用 UTF-16 会更好。然后你压缩 UTF-8 这也是合理的。最后传输用base64编码,也是合理的。

减少要传输的数据大小的最明显方法是省略 base64 步骤。如果您可以传输在步骤 2 中生成的压缩字节,那么您将传输更少。 Base64 使用 4 个字节编码 3 个字节,因此 base64 编码数据的大小比输入数据大三分之一。

另一种方法可能是使用比 zlib 更好的压缩算法,但同样存在限制。通常更好的压缩是以增加计算时间为代价的。