继上一个问题here之后,如何重构以下(可怕但工作正常的POC)代码只支持0到2147483647之间的整数?
<?php
$lower = 'abcdefghijklmnopqrstuvwxyz';
$upper = strtoupper($lower);
$numbers = '1234567890';
$chars = $upper.$lower.$numbers;
$map = [];
for ($i = 1; $i <= strlen($chars); $i++) {
$map[$chars{$i - 1}] = $i;
}
$map[' '] = count($map) + 1;
function map($char)
{
global $map;
return $map[$char];
}
function encode($char)
{
global $map;
return sprintf('%06s', decbin($map[$char]));
}
function bytesToInt(array $bytes)
{
$bytes = array_values($bytes);
$int = (int) ($bytes[3]<<24) | ($bytes[2]<<16) | ($bytes[1]<<8) | ($bytes[0]);
if ($int >= 2147483648) {
$int -= 4294967296;
}
return $int;
}
$message = $argv[1];
$length = strlen($message);
if ($length > 21) {
die('nope');
}
echo 'Encoding "'.$message.'" which is '.$length.' bytes long'."\n";
$max = 128;
$joined = '';
for ($i = 0; $i < $length; $i++) {
$joined .= encode($message{$i});
}
$length = strlen($joined);
$joined .= str_repeat('0', $max - $length);
$length = strlen($joined);
echo $joined."\n";
$bytes = [];
$position = 0;
$bits = 8;
while ($position < $max) {
$byte = substr($joined, $position, $bits);
$bytes[] = bindec($byte);
$position += $bits;
}
print_r($bytes);
$joined = '';
for ($i = 0; $i < 16; $i += 4) {
$int = bytesToInt(array_slice($bytes, $i, 4))."\n";
echo "Int: {$int}\n";
$back = unpack("C*", pack("L", $int));
print_r($back);
foreach ($back as $byte) {
$joined .= sprintf('%08s', decbin($byte));
}
}
echo $joined."\n";
$map = array_flip($map);
print_r($map);
$position = 0;
$message = '';
while ($position < $max) {
$dec = bindec(substr($joined, $position, 6));
if ($dec === 0) {
break;
}
$char = $map[$dec];
$message .= $char;
$position += 6;
}
echo $message."\n";
当前代码允许21个字符集[0-9A-za-z]编码为-2147483647和2147483647之间的整数。
我怀疑21个字符限制显然必须根据新要求减少到10或11个字符,这对我的用例来说是令人满意的。
答案 0 :(得分:0)
对不起,但是代码太多了。
不仅仅是针对这个问题,但如果您在上一个问题中提到过您只需要在4位或32位整数中存储10或11个字母数字字符,那么您就不需要了一共编码为6个字节,如11&lt; 16。
只需将字符的ASCII值存储在字节数组中,然后将其转换为4个整数。
整数的最高有效位是符号位,它在设置(1)时使整数为负。使用字符的ASCII值,所有这些都将是&lt; 127,该位,值为128,永远不会被设置。