php 超过64位进制和10进制的转换

有时候想把一个很大的数尽量用更少的空间存储起来,那么就可以采用很大的进制来存储它,比如说,一个大于等于10小于等于16数字使用10进制就需要两位,使用16进制就只需要1位,那就等于帮程序省了一位的空间,数字越大,进制越高,效果也就越明显。

举例如下:

1000000的转换比较二进制八进制十进制十六进制
转换结果

11110100001001000000

3641100

1000000

f4240

占用存储长度

20

7

7

5

现在我们可以看到,十六进制能省下2个长度,然后我们能不能得到一个更高进制?那就能省更多空间了,且看代码

<?php
// need bcmath extension
function binaryTo(int $num = 0) {
  $dict = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./?<>{}[]|()';
  $to = strlen($dict);
  $ret = '';
  do {
    $ret = $dict[bcmod($num, $to)] . $ret; //bcmod取得高精确度数字的余数。
    $num = bcdiv($num, $to);  //bcdiv将二个高精确度数字相除。
  } while ($num > 0);
  return $ret;
}

function binaryFrom(string $num = '') {
  $num = strval($num);
  $dict = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./?<>{}[]|()';
  $from = strlen($dict);
  $len = strlen($num);
  $dec = 0;
  for($i = 0; $i < $len; $i++) {
    $pos = strpos($dict, $num[$i]);
    $dec = bcadd(bcmul(bcpow($from, $len - $i - 1), $pos), $dec);
  }
  return $dec;
}

var_dump(binaryTo(1000000));
var_dump(binaryFrom('2rWp'));

这个代码可能会报错,如果报错请检查是不是没开启 bcmath 扩展,没有这个扩展的你就装一下,sudo apt search 然后install 一下

此时我们就可以把这个表格更新了,我们看到现在使用这个函数得到的进制结果是 2rWp 那么长度就是4位。

表格更新如下:

1000000的转换比较二进制八进制十进制十六进制七十五进制
转换结果1111010000100100000036411001000000f4240

2rWp

占用存储长度207754

我们可能觉得7个长度缩减到4个长度,这并不算什么,但是如果你有一个很大数据量的存储文本,你存储了大量的这种id int型的数据,那么就会占用很大的空间,此时你采用这种方式转换存储一下,发现文件能减少30%左右,那这个时候该文件的读写就能快很多,能减少服务器各方面(硬盘空间 内存空间等)压力,数据量越多,其效果就越明显。

当然这里面有副作用,比如我添加的数据需要转换一次回到10进制,才能给前台使用,查询的时候也要先转为75进制进行查询,特殊格式如果用到了]})这种的时候可能会影响你的业务逻辑,那你需要根据自身业务情况处理一下,或者换其他的符号作为进制符号。