【发布时间】:2015-10-15 16:20:51
【问题描述】:
继我之前的问题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";
该代码目前允许将 [0-9A-za-z] 集的 21 个字符编码为介于 -2147483647 和 2147483647 之间的整数。
我怀疑 21 个字符的限制显然必须根据新要求减少到 10 或 11 个字符左右,这对我的用例来说是令人满意的。
【问题讨论】: