如何在PHP中压缩/解压缩长查询字符串?

jod*_*eci 31 php

我怀疑这是否是加密,但我找不到更好的短语. 我需要传递一个像这样的长查询字符串:

http://test.com/test.php?key=[some_very_loooooooooooooooooooooooong_query_string]
Run Code Online (Sandbox Code Playgroud)

查询字符串包含没有敏感信息,因此在这种情况下我并不真正关心安全性.它只是......好吧,太长又丑.是否有一个库函数可以让我将查询字符串编码/加密/压缩成类似于md5()的结果(类似于,总是一个32个字符的字符串),但解码/解密/解压缩?

Gum*_*mbo 43

你可以尝试的组合gzdeflate(生放气格式)来压缩数据和base64_encode只使用那些未经允许的百分比编码字符(另外交换角色+,并/通过-_):

$output = rtrim(strtr(base64_encode(gzdeflate($input, 9)), '+/', '-_'), '=');
Run Code Online (Sandbox Code Playgroud)

反之亦然:

$output = gzinflate(base64_decode(strtr($input, '-_', '+/')));
Run Code Online (Sandbox Code Playgroud)

这是一个例子:

$input = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';

// percent-encoding on plain text
var_dump(urlencode($input));

// deflated input
$output = rtrim(strtr(base64_encode(gzdeflate($input, 9)), '+/', '-_'), '=');
var_dump($output);
Run Code Online (Sandbox Code Playgroud)

这种情况下的节省约为23%.但是这种压缩程序的实际效率取决于您使用的数据.


dec*_*eze 34

基本前提非常困难.传输URL中的任何值意味着您被限制为ASCII字符的子集.使用任何类型的压缩gzcompress都会减小字符串的大小,但会产生二进制blob.但是,二进制blob无法在URL中传输,因为它会产生无效字符.要使用ASCII子集传输该二进制blob,您需要以某种方式对其进行编码并将其转换为ASCII字符.

因此,您可以将ASCII字符转换为其他字符,然后转换为ASCII字符.

但实际上,大多数情况下,您开始使用的ASCII字符已经是最佳长度.这是一个快速测试:

$str = 'Hello I am a very very very very long search string';
echo $str . "\n";
echo base64_encode(gzcompress($str, 9)) . "\n";
echo bin2hex(gzcompress($str, 9)) . "\n";
echo urlencode(gzcompress($str, 9)) . "\n";

Hello I am a very very very very long search string
eNrzSM3JyVfwVEjMVUhUKEstqkQncvLz0hWKUxOLkjMUikuKMvPSAc+AEoI=
78daf348cdc9c957f05448cc554854284b2daa442772f2f3d2158a53138b9233148a4b8a32f3d201cf801282
x%DA%F3H%CD%C9%C9W%F0TH%CCUHT%28K-%AAD%27r%F2%F3%D2%15%8AS%13%8B%923%14%8AK%8A2%F3%D2%01%CF%80%12%82
Run Code Online (Sandbox Code Playgroud)

如您所见,原始字符串是最短的.在编码的压缩中,base64是最短的,因为它使用最大的字母表示二进制数据.它仍然比原来更长.

对于某些非常特定的字符组合以及一些压缩到ASCII可表示数据的非常特定的压缩算法,可能会实现一些压缩,但这相当理论化. 更新:实际上,这听起来太消极了.问题是你需要弄清楚压缩是否对你的用例有意义.不同的数据压缩不同,不同的编码算法工作方式不同.而且,较长的弦可以实现更好的压缩比.在一些可以实现压缩的地方可能有一个甜蜜的地方.你需要弄清楚你是否在大多数时间都在这个最佳位置.

像md5这样的东西是不合适的,因为md5是一个哈希,这意味着它是不可逆的.您无法从中获取原始值.

我担心你只能通过POST发送参数,如果它在URL中不起作用.

  • 实际上你不能确定任何编码会导致更长的字符串作为原始字符串.这真的取决于原始字符串.如果压缩足够好,那么甚至编码版本也可以更短.我用base64尝试了我的例子,它比原始字符串短.但你在某种程度上是正确的,因为可能是最多的时间,编码版本会更长. (4认同)

小智 12

这对我很有用:

$out = urlencode(base64_encode(gzcompress($in)));
Run Code Online (Sandbox Code Playgroud)

节省了很多.

$in = 'Hello I am a very very very very long search string' // (51)
$out = 64

$in = 500
$out = 328

$in = 1000
$out = 342

$in = 1500
$out = 352
Run Code Online (Sandbox Code Playgroud)

所以弦越长,压缩越好.压缩参数似乎没有任何影响.


Fel*_*ing 5

更新:
gzcompress()不会帮助你.例如,如果你采取Pekka的答案:

字符串长度:640
压缩字符串长度:375
URL编码字符串长度:925
(使用base64_encode,它只有500个字符;))

所以这种方式(通过URL传递数据)可能不是最好的方式......

如果您不超过以字符串的URL限制,你为什么要关心如何串样子?我认为无论如何都会自动创建,发送和处理,不是吗?

但是,如果您想将其用作电子邮件中的某种确认链接,则必须考虑简短且易于为用户键入的内容.您可以,例如,将所有需要的数据存储在数据库中并创建某种令牌.


也许gzcompress()可以帮到你.但这会导致不允许的字符,所以你也必须使用urlencode()它(这会使字符串更长,更丑;)).