Pek*_*ica 9 php algorithm encoding
是否有一种常见的方法来编码和解码任意数据,因此编码的最终结果只包含数字 - 如base64_encode但没有字母?
虚构的例子:
$encoded = numbers_encode("Mary had a little lamb");
echo $encoded; // outputs e.g. 12238433742239423742322 (fictitious result)
$decoded = numbers_decode("12238433742239423742322");
echo $decoded; // outputs "Mary had a little lamb"
Art*_*cto 13
您可以将(单字节字符)字符串视为基本256编码的数字,其中"\ x00"表示0,''(空格,即"\ x20")表示32,依此类推,直到"\ xFF",其中代表255.
仅通过将表示改变为基数10可以实现仅具有数字0-9的表示.
请注意,"base64编码"实际上不是基本转换.base64将输入分成3个字节(24位)的组,并分别对这些组进行基本转换.这很有效,因为24位的数字可以用基数64中的四位数表示(2 ^ 24 = 64 ^ 4).
这或多或少是el.pescado所做的 - 他将输入数据拆分为8位,然后将数字转换为基数10.但是,这种技术相对于基本64位编码有一个缺点 - 它不能正确对齐字节边界.要表示一个8位的数字(无符号时为0-255),我们需要基数为10的三位数.但是,最左边的数字比其他数字的信息少.它可以是0,1或2(对于无符号数).
基数10中的数字存储log(10)/ log(2)位.无论你选择的块大小,你都永远无法将表示与8位字节对齐(在我之前的段落中描述的"对齐"意义上).因此,最紧凑的表示是基本转换(您可以看到它只是一个只有一个大块的"基本编码").
这是bcmath的一个例子.
bcscale(0);
function base256ToBase10(string $string) {
    //argument is little-endian
    $result = "0";
    for ($i = strlen($string)-1; $i >= 0; $i--) {
        $result = bcadd($result,
            bcmul(ord($string[$i]), bcpow(256, $i)));
    }
    return $result;
}
function base10ToBase256(string $number) {
    $result = "";
    $n = $number;
    do {
        $remainder = bcmod($n, 256);
        $n = bcdiv($n, 256);
        $result .= chr($remainder);
    } while ($n > 0);
    return $result;
}
对于
$string = "Mary had a little lamb";
$base10 = base256ToBase10($string);
echo $base10,"\n";
$base256 = base10ToBase256($base10);
echo $base256;
我们得到
36826012939234118013885831603834892771924668323094861 Mary had a little lamb
由于每个数字仅对log(10)/log(2)=~3.32193位进行编码,因此预计该数字将延长140%(不会像el.pescado的答案那样延长200%).
那么,这将是"基础8"编码而不是基础64.这更好地称为八进制.
所有Base64都将比特流转换为6比特块(0-63),并从64个字符的字符集中分配一个字符.Octal使用3位,0-7.所以它可以使用ABCDEFGH,而是使用0-7.您不能(轻松)使用0-9,因为0-9最多为4位,但不完全是4位.这就是使它成为二进制数据的糟糕编码的原因.