forked from flanchan/doushio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.2 KiB
103 lines
2.2 KiB
5 years ago
|
<?PHP
|
||
|
|
||
|
#error_reporting(E_ALL);
|
||
|
|
||
|
// Examples:
|
||
|
// $str = base85::encode("Hello world!");
|
||
|
// $str = base85::decode(":e4D*;K$&\Er");
|
||
|
|
||
|
class base85
|
||
|
{
|
||
|
|
||
|
public static function decode($str) {
|
||
|
$str = preg_replace("/ \t\r\n\f/","",$str);
|
||
|
$str = preg_replace("/z/","!!!!!",$str);
|
||
|
$str = preg_replace("/y/","+<VdL/",$str);
|
||
|
|
||
|
// Pad the end of the string so it's a multiple of 5
|
||
|
$padding = 5 - (strlen($str) % 5);
|
||
|
if (strlen($str) % 5 === 0) {
|
||
|
$padding = 0;
|
||
|
}
|
||
|
$str .= str_repeat('u',$padding);
|
||
|
|
||
|
$num = 0;
|
||
|
$ret = '';
|
||
|
|
||
|
// Foreach 5 chars, convert it to an integer
|
||
|
while ($chunk = substr($str, $num * 5, 5)) {
|
||
|
$tmp = 0;
|
||
|
|
||
|
foreach (unpack('C*',$chunk) as $item) {
|
||
|
$tmp *= 85;
|
||
|
$tmp += $item - 33;
|
||
|
}
|
||
|
|
||
|
// Convert the integer in to a string
|
||
|
$ret .= pack('N', $tmp);
|
||
|
|
||
|
$num++;
|
||
|
}
|
||
|
|
||
|
// Remove any padding we had to add
|
||
|
$ret = substr($ret,0,strlen($ret) - $padding);
|
||
|
|
||
|
return $ret;
|
||
|
}
|
||
|
|
||
|
public static function encode($str) {
|
||
|
$ret = '';
|
||
|
$debug = 0;
|
||
|
|
||
|
$padding = 4 - (strlen($str) % 4);
|
||
|
if (strlen($str) % 4 === 0) {
|
||
|
$padding = 0;
|
||
|
}
|
||
|
|
||
|
if ($debug) {
|
||
|
printf("Length: %d = Padding: %s<br /><br />\n",strlen($str),$padding);
|
||
|
}
|
||
|
|
||
|
// If we don't have a four byte chunk, append \0s
|
||
|
$str .= str_repeat("\0", $padding);
|
||
|
|
||
|
foreach (unpack('N*',$str) as $chunk) {
|
||
|
// If there is an all zero chunk, it has a shortcut of 'z'
|
||
|
if ($chunk == "\0") {
|
||
|
$ret .= "z";
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Four spaces has a shortcut of 'y'
|
||
|
if ($chunk == 538976288) {
|
||
|
$ret .= "y";
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ($debug) {
|
||
|
var_dump($chunk); print "<br />\n";
|
||
|
}
|
||
|
|
||
|
// Convert the integer into 5 "quintet" chunks
|
||
|
for ($a = 0; $a < 5; $a++) {
|
||
|
$b = intval($chunk / (pow(85,4 - $a)));
|
||
|
$ret .= chr($b + 33);
|
||
|
|
||
|
if ($debug) {
|
||
|
printf("%03d = %s <br />\n",$b,chr($b+33));
|
||
|
}
|
||
|
|
||
|
$chunk -= $b * pow(85,4 - $a);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If we added some null bytes, we remove them from the final string
|
||
|
if ($padding) {
|
||
|
$ret = preg_replace("/z$/",'!!!!!',$ret);
|
||
|
$ret = substr($ret,0,strlen($ret) - $padding);
|
||
|
}
|
||
|
|
||
|
return $ret;
|
||
|
}
|
||
|
|
||
|
} // End of base85 class
|