【问题标题】:php is converting base 16 to base 2 incorrectlyphp错误地将base 16转换为base 2
【发布时间】:2013-09-21 11:14:46
【问题描述】:

为什么我会从我的函数中得到这个输出?

echo $var = hash_hmac('ripemd160', 'http://www.weburlhere.org', 0, 0);
echo "\r\n";
echo $converted = base_convert($var, 16, 2);
echo "\r\n";

输出:

407a9d8868a678e12d9fc0264f9ae11e8761b557
0000000000000000000000000000000000000000000000000000000000000000

base_convert($var, 16, 10) 输出

1421821959848150668406846884086820088622688484226 正确。

另外,作为一个附带问题(对此有加分!)我假设ripemd160 为我提供了每个输入原像的唯一标识符。我正在尝试创建一个 url-shortening 服务,将 URL 从任何长度缩短为其哈希摘要(我假设使用 base64_encode($converted) 将二进制文件转换为 base64 将进一步缩短 URL)。这是正确的,这是个好主意吗?

【问题讨论】:

  • 您为什么使用hash_hmac。有必要吗
  • 从 URL 派生一个简短且唯一的值(例如哈希)不会很好。在某个地方保留一个计数器会更容易,并且 base-36(以避免大小写冲突)对其进行哈希处理以使其尽可能短。我不知道二进制数是如何进入其中的,但是......
  • 我认为 base64 编码会提供更短的 URL,所以我必须先将十六进制转换为二进制,因为 base64_encode 需要二进制输入数据(或者我是这么认为的)。
  • @bvpx,Sverri M. Olsen 的想法是自动递增编号(数据库中的 ID),并将 ID 转换为更高的基数(可以是 base64)以提供更短的链接而不是散列URL 并将其用作 ID。
  • 哈希的使用在我的应用程序中有一个目的,这与本次讨论有点无关,无论如何也不适合评论框的范围。

标签: php encoding hash base hmac


【解决方案1】:

base_convert上的PHP文档说

base_convert() 由于属性的原因,可能会丢失大数的精度 与使用的内部“double”或“float”类型有关。请参阅 手册中的浮点数部分更具体 信息和限制。

因此,您不能依赖此函数来转换大数。但是,手动编写一个从 16 进制转换为 2 进制的函数非常容易。

function hex2bin($hex) {
    $table = array('0000', '0001', '0010', '0011', 
                   '0100', '0101', '0110', '0111',
                   '1000', '1001', 'a' => '1010', 'b' => '1011', 
                   'c' => '1100', 'd' => '1101', 'e' => '1110', 
                   'f' => '1111');
    $bin = '';
    
    for($i = 0; $i < strlen($hex); $i++) {
        $bin .= $table[strtolower(substr($hex, $i, 1))];
    }
    
    return $bin;
}
echo hex2bin('407a9d8868a678e12d9fc0264f9ae11e8761b557');

我假设将二进制文件转换为 base64 base64_encode($converted) 将进一步缩短 URL)。这是 正确,这是个好主意吗

是的,它更短。它比二进制短 32 倍,比 base-16 短 4 倍。但是,ripemd160 不保证为每个链接提供唯一标识符。仍然有一些碰撞(我什至不知道它会多么罕见)。

【讨论】:

  • 注意:GMP extension 在这里可能会有所帮助,尤其是 gmp_strval 函数。不过,将十六进制转换为二进制非常简单,只需几行代码即可完成。
  • 谢谢,但需要选择另一个名字,因为Cannot redeclare hex2bin()
  • @a55,你是对的。我做出了改变。
  • 所以请把a =&gt;改成'a' =&gt;,谢谢
【解决方案2】:

根据 PHP 手册,base_convert() 被限制为 doublefloat 32 位精度。您可以使用gmp库来处理任意长度的数字。

sample code 也来自 PHP 手册页:

/* use gmp library to convert base. gmp will convert numbers > 32bit
 * @author lindsay at bitleap dot com
 * @link you can execute this code at http://ideone.com/FT29qo
 */
function gmp_convert($num, $base_a, $base_b)
{
    return gmp_strval ( gmp_init($num, $base_a), $base_b );
}

【讨论】:

  • Call to undefined function gmp_strval() 然后apt install php-gmp
猜你喜欢
  • 2013-03-05
  • 2018-05-03
  • 2014-11-22
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多