您需要研究不同的压缩方法和算法,因为您可以压缩的程度取决于算法。例如,这是一个非常幼稚且可能效率低下的算法。
<?php
$str = '2222342022223411112203302222232222122221230222';
echo $str . "\r\n";
$values = [
];
$lastChar = null;
$value = [];
foreach (str_split($str) as $character) {
if ($lastChar === null) {
$value = ['number' => $character, 'count' => 1];
$lastChar = $character;
continue;
}
if ($lastChar !== $character) {
$values[] = $value;
$value = ['number' => $character, 'count' => 0];
}
$value['count']++;
$lastChar = $character;
}
$values[] = $value;
function combine($a, $b) {
return str_pad(base_convert($a, 10, 2), 5, "0", STR_PAD_LEFT) . str_pad(base_convert($b, 10, 2), 3, "0", STR_PAD_LEFT);
}
function compressValue($value) {
$return = '';
if ($value['count'] > 8) {
$return .= compressValue(['number' => $value['number'], 'count' => $value['count'] - 8]);
$value['count'] = $value['count'] % 8;
}
$return .= combine($value['count'], $value['number']);
return $return;
};
$values = array_map('compressValue', $values);
$values = join("", $values);
$values = str_split($values, 8);
$values = array_map(function ($value) {
$ord = chr(bindec($value));
return $ord;
}, $values);
$values = join("", $values);
echo $values . "\r\n";
echo strlen($values) . "\r\n";
echo strlen($str) . "\r\n";
输出...很多不可读的字符。那有一个23的strlen!比原来的 46 还短!
那么它有什么作用呢?它接受字符串,并说“有 4 个 2,然后是 1x3、1x4、1x2 1x0、4x2”等等。然后它把它们变成一个组合的二进制文件。我们将使每个 8 位二进制文件成为一种长度的字母。所以 4x2 因为 00100 。 010 由于所有数字都小于 5,因此我们使用二进制的最后 3 位作为数字,其他 5 位作为计数。如果超过 31(我们可以存储在 5 位中的最大计数),我们将把其余的存储在下一个字节中。
然后,我们有一个很长的二进制字符串,所以我们将它转换为十六进制。
所以,要转换回来,我们可以从十六进制转换为二进制,然后将其拆分为 8 位数字的块,并取每个块的前 5 个,将其转换为 dec 并取接下来的 3 个块,将其转换为 dec,然后按照第一个 dec 中的次数重复第二个 dec
话虽如此,这只是我第一次尝试压缩算法,我对它们了解不多。因此,如果您想通过 Google 查找更多信息,并研究不同的算法,您可能会找到更有效的方法。我的程序中可能也有错误,这是一个简短的概念证明
解码它的代码是
$values = str_split($values);
$values = array_map(function ($value) {
return str_pad(decbin(ord($value)), 8, "0", STR_PAD_LEFT);
}, $values);
$values = array_map(function ($value) {
$count = substr($value, 0, 5);
$number = substr($value, 5, 3);
$count = base_convert($count, 2, 10);
$number = base_convert($number, 2, 10);
return str_repeat($number, $count);
}, $values);
echo join("", $values);