将非常大的数字编码到字符串中

时间:2015-10-14 22:26:16

标签: php math encoding logarithm

我一直在尝试使用PHP将非常大的整数编码为大写字母序列。将值从0到25分配到A~Z我已将10亿缩减为 DGEHTYM 。如果实现了工作算法,使用不同的情况,数字甚至符号,结果字符串可以更短。然而,我的目标只是大写字母串,也许还有数字字符,以使它更短但不是必须的。

使用笔,纸和我的手机计算器进行编码:

  • 发现 26 的最高功率低于10亿(php具有函数log)。 10亿,它是6.所以 26 ^ 6 = 308,915,776
  • 1,000,000,000 308,915,776 3.237 有很多小数
  • 3 D 。我们得到了第一封信!
  • 现在我们将一遍又一遍地做同样的事情,直到我们得到一个整数:取走整个部分并乘以 26 留下的小数。我们拿走的每一个都是一封信。 10亿次我循环6次直到我得到12次,这是 M

也许有一种更聪明的方法来实现这一点,但我还没有想到它。

或许我应该以不同的方式完成它,但由于缺乏更好的方法,我试图在PHP中复制我的计算,但我遇到了问题: 1:它非常难以编码编码的数字将以 A (0)结尾,例如 1326 ,这将是 BZA 和2:我无法编码设法让PHP检测数字是否有或没有小数。我不得不继续将它转换为字符串并寻找一个点。

解码字符串更容易。从从右到左,你将每个字母的值乘以26提升到其位置的幂,除了第一个,他们将它们全部加起来:

D => 3 x (26^6) = 926,747,328
G => 6 x (26^5) = 71,288,256
E => 4 x (26^4) = 1,827,904
H => 3 x (26^3) = 123,032
T => 19 x (26^2) = 12,844
Y => 24 x 26 = 624
M => 12
926,747,328 + 71,288,256 + 1,827,904 + 123,032 + 12,844 + 624 + 12 = 1,000,000,000

有一个类似的问题here,但回答的人似乎并不了解OP想要完成的任务。

1 个答案:

答案 0 :(得分:1)

您正在从基数10转换为26,这是在base_convertgmp_strval等内置函数可以处理的范围内。它们会以0-9和a-p的形式给出数字,因此您只需要将它们转换为strtr后的内容。

$translate = array_combine(
    array_merge(range(0, 9), range('a', 'p')),
    range('A', 'Z')
);

echo strtr(base_convert(1000000000, 10, 26), $translate), "\n";
echo strtr(base_convert(1326, 10, 26), $translate), "\n";

//Or if you're working with really big numbers (beyond PHP_INT_MAX):
echo strtr(gmp_strval(1000000000, 26), $translate), "\n";
echo strtr(gmp_strval(1326, 26), $translate);

输出:

DGEHTYM
BZA
DGEHTYM
BZA

或者手动完成,这样可以轻松添加/删除不同基础和编码的符号。基本上你将输入数字除以基数,使用余数来查找该位置的相应符号,然后重复分割的结果。

function base10_to_whatevs($num, array $digits)
{
    $result = '';
    $base = count($digits);
    while ($num > 0) {
        $remainder = $num % $base;
        $num = ($num - $remainder) / $base;
        $result = $digits[$remainder] . $result;
    }
    return $result;
}

$letters = range('A', 'Z');
echo base10_to_whatevs(1000000000, $letters), "\n";
echo base10_to_whatevs(1326, $letters);
DGEHTYM
BZA