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

如何在PHP中压缩/解压缩长查询字符串?,php,Php,我怀疑这是否是加密,但我找不到更好的短语。我需要传递一个长查询字符串,如下所示: http://test.com/test.php?key=[some_very_loooooooooooooooooooooooong_query_string] 查询字符串不包含敏感信息,因此我并不真正关心本例中的安全性。只是…嗯,太长太难看了。是否有一个库函数可以让我将查询字符串编码/加密/压缩为类似于md5()的结果(与中类似,始终是32个字符的字符串),但可以解码/解密/解压缩 base64_encode

我怀疑这是否是加密,但我找不到更好的短语。我需要传递一个长查询字符串,如下所示:

http://test.com/test.php?key=[some_very_loooooooooooooooooooooooong_query_string]

查询字符串不包含敏感信息,因此我并不真正关心本例中的安全性。只是…嗯,太长太难看了。是否有一个库函数可以让我将查询字符串编码/加密/压缩为类似于md5()的结果(与中类似,始终是32个字符的字符串),但可以解码/解密/解压缩

base64_encode
使字符串无法读取(当然很容易解码),但会将音量放大33%

urlencode()
将任何不适合URL的字符转换为URL编码的对应字符。如果您的目标是使字符串在URL中工作,那么这可能是正确的方法

如果您有一个运行的会话,您也可以考虑将查询字符串放入一个具有随机(小)数的会话变量中,并将该随机数放入GET字符串中。当然,此方法不会比当前会话持续更长时间


请注意,由于服务器和浏览器的限制,GET字符串的大小不应超过1-2 KB。

更新:
gzcompress()
对您没有帮助。例如,如果您采用Pekka的答案:

字符串长度:640
压缩字符串长度:375
URL编码字符串长度:925
(使用base64_编码,仅500个字符;)

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

如果字符串没有超过URL限制,为什么还要关心字符串的外观?我想它是自动创建、发送和处理的,不是吗

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



也许我能帮你。但这将导致不允许使用字符,因此您也必须使用(这会使字符串变长、变丑;)。

对于长/非常长的字符串值,您希望使用POST方法而不是GET

要获得良好的编码,您可能需要尝试urlencode()/urldecode()

或htmlentities()/html\u entity\u decode()

还要注意将“%2F”转换为“/”字符(目录分隔符)到浏览器中。如果只使用urlencode,可能需要对其进行替换


我不建议对GET参数进行压缩。

基本前提非常困难。传输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
如您所见,原始字符串是最短的。在编码压缩中,base64是最短的,因为它使用最大的字母表来表示二进制数据。但它仍然比原来的要长

对于一些非常特定的字符组合和一些非常特定的压缩算法(压缩为ASCII表示的数据),可能实现一些压缩,但这是理论上的更新:实际上,这听起来太消极了。问题是,您需要弄清楚压缩对您的用例是否有意义。不同的数据压缩方式不同,不同的编码算法工作方式也不同。此外,更长的字符串可以实现更好的压缩比。可能在某个地方有一个最佳点,可以实现一些压缩。你需要弄清楚自己是否大部分时间都处于最佳状态

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


恐怕您只能通过POST发送参数,如果它在URL中不起作用。

您可以尝试组合(原始deflate格式)来压缩数据,并仅使用不允许百分比编码的字符(另外通过
-
\uuu
交换字符
+
/
):

反之亦然:

$output = gzinflate(base64_decode(strtr($input, '-_', '+/')));
以下是一个例子:

$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);

这种情况下节省的成本约为23%。但此压缩过程的实际效率取决于您使用的数据。

这对我来说非常有用:

$out = urlencode(base64_encode(gzcompress($in)));
节省了很多

$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

因此字符串越长,压缩效果越好。压缩参数似乎没有任何效果。

这些函数将压缩和解压缩字符串或数组

有时,您可能需要获取一个数组

function _encode_string_array ($stringArray) {
    $s = strtr(base64_encode(addslashes(gzcompress(serialize($stringArray),9))), '+/=', '-_,');
    return $s;
}

function _decode_string_array ($stringArray) {
    $s = unserialize(gzuncompress(stripslashes(base64_decode(strtr($stringArray, '-_,', '+/=')))));
    return $s;
}

基本上,这就像他们说的:压缩文本,然后以一种有用的方式编码发送。但是

1)由于字典的原因,常用的压缩方法比文本压缩方法要重。如果数据总是由确定的数据块(如文本中的单词或音节[3],数字和一些符号)组成的未确定顺序,则可以始终使用相同的静态词典,而不发送(不要将其粘贴到URL上)。然后可以节省字典的空间

1.a)如果您已经发送了该语言(或者如果它总是相同的),您可以为每个语言生成一个字典

1.b)利用格式限制。如果你知道我
function _encode_string_array ($stringArray) {
    $s = strtr(base64_encode(addslashes(gzcompress(serialize($stringArray),9))), '+/=', '-_,');
    return $s;
}

function _decode_string_array ($stringArray) {
    $s = unserialize(gzuncompress(stripslashes(base64_decode(strtr($stringArray, '-_,', '+/=')))));
    return $s;
}
samplemail1@gmail.com,samplemail2@yahoo.com.ar,samplemail3@idontknowyou.com => samplemail1:1,samplemail2:5,samplemail3@idontknowyou:1
name=[TEXT 1]&phone=[PHONE]&mail=[MAIL]&desc=[TEXT 2]&create=[DATE 1]&modified=[DATE 2]&first=[NUMBER 1]&last=[NUMBER 2]
[TEXT1]|[PHONE]|[MAIL]|[TEXT 2]|[DATE 1]|[DATE 2]|[NUMBER 1][NUMBER 2]
[DATE 1][DATE 2][NUMBER 1][NUMBER 2][PHONE][MAIL]|[TEXT 1]|[TEXT 2]
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.:,;+*-_/()$=!@?~'
<?php
    $test_str="33036,33037,33038,38780,38772,37671,36531,38360,39173,38676,37888,36828,39176,39196,37321,36840,38519,37946,36543,39287,38989,38976,36804,38880,38922,38292,38507,38893,38993,39035,37880,38897,38378,36880,38492,38910,36868,38196,38750,37938,39268,38209,36856,36767,37936,36805,39248,36777,39027,39056,38987,38779,38919,38771,36851,38675,37887,38246,38791,38783,38661,37899,36846,36834,39263,37928,36822,37947,38992,38516,39177,38904,38896,37320,39217,37879,38293,38511,38774,37670,38185,37927,37939,38286,38298,38977,37891,38881,38197,38457,36962,39171,36760,36748,39249,39231,39191,36951,36963,36755,38769,38891,38654,38792,36863,36875,36956,36968,38978,38299,36743,36753,37896,38926,39270,38372,37948,39250,38763,38190,38678,36761,37925,36776,36844,37323,38781,38744,38321,38202,38793,38510,38288,36816,38384,37906,38184,38192,38745,39218,38673,39178,39198,39036,38504,36754,39180,37919,38768,38195,36850,38203,38672,38882,38071,39189,36795,36783,38870,38764,39028,36762,36750,38980,36958,37924,38884,37920,38877,36858,38493,36742,37895,36835,37907,36823,38762,38361,37937,38373,37949,36950,39202,38495,38291,36533,39037,36716,38925,37620,38906,37878,37322,38754,36818,39029,39264,38297,38517,36969,38905,36957,36789,36741,37908,38302,38775,39216,36812,38767,36845,36849,39181,39168,38671,39188,38490,36961,39201,36717,38382,38070,37868,38984,36770,38981,38494,36807,38885,36759,36857,38924,39038,38888,38876,36879,37897,36534,36764,37931,38254,39030,38990,37909,38982,38290,36848,37857,37923,38249,38658,38383,36813,36765,36817,37263,36769,37869,38183,36861,38206,39031,36800,36788,36972,38508,38303,39051,38491,38983,38759,36740,37958,36967,37930,39174,39182,36806,36867,36855,39222,37862,36752,38242,37965,38894,38182,37922,37918,36814,36872,38886,36860,36527,38194,38975,36718,39224,37436,39032";

    echo(strlen($test_str)); echo("<br>");

    echo(strlen(base64_encode(gzcompress($test_str,9)))); echo("<br>");

    echo(strlen(bin2hex(gzcompress($test_str, 9)))); echo("<br>");

    echo(strlen(urlencode(gzcompress($test_str, 9)))); echo("<br>");

    echo(strlen(rtrim(strtr(base64_encode(gzdeflate($test_str, 9)), '+/', '-_'), '=')));
?>
1799  (original length string)
928   (51.58% compression)
1388
1712
918   (51.028% compression)