将字母数字字符串存储为4个32位整数


Storing an alphanumeric string in 4 32bit integers

继续我之前的问题,在这里,如何重构以下(糟糕但有效的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个字符,这对我的用例是满意的。

很抱歉,但这是太多的代码。

不仅针对这个问题,而且如果你在上一个问题中提到你只需要在4个32位整数中存储10或11个字母数字字符,或者简单地说,16字节,你就不需要总共编码成6个字节,如11 <16 .

只需将字符的ASCII值存储在字节数组中并将其转换为4个整数。

整数的最高有效位是符号位,当设置(1)时,该整数为负。使用字符的ASCII值,所有字符都将为<127,这个位的值为128,永远不会被设置。