php int 32 64,PHP 中CRC32 在32位系统和64位系统中的坑

很多小伙伴在对字符串进行取模或者做指纹存储的时候用到CRC32这个函数.

今天就来分享下CRC32隐藏的坑.

假如我根据一个连接地址,对这个连接地址进行分表.

http://www.xxx.com/www/index/ad/1/count/123/do/click/**** 等一串连接

小伙伴们肯定会想到用

$sign = crc32(md5($link));

然后在根据sign 进行取模.

这句代码有个坑,看完接下来的解释在回过头来说。

首先PHP手册上针对CRC32已经给出警告

Warning

由于 PHP 的整数是带符号的,所以在 32 位系统上许多 crc32 校验码将返回负整数。 尽管在 64 位上所有 crc32() 的结果将都是正整数。

接下来分析下这句话的隐藏含义:

crc32函数会按照php中的两个常量参考计算 PHP_INT_SIZE,PHP_INT_MAX

这两个常量的定义:

整型数的字长和平台有关,尽管通常最大值是大约二十亿(32 位有符号)。PHP 不支持无符号整数。Integer值的字长可以用常量PHP_INT_SIZE来表示,自 PHP 4.4.0 和 PHP 5.0.5后,最大值可以用常量PHP_INT_MAX来表示。

输出下32位中PHP_INT_SIZE:4,PHP_INT_MAX:2147483647

输出下64位中PHP_INT_SIZE:8,PHP_INT_MAX:9223372036854775807

则32位无符号整形

2^32-1 = 4294967295

由于前面说了php 不支持无符号整形,所以md5后 再 crc32的值一旦超出有符号整形的最大范围则就溢出。

所以在回过头来看顶部的例子,就看出端倪来了。

如何调整

public function getModSign($str){

$unsign = sprintf('%u', crc32($string));

if ($unsign > 2147483647)

{

$unsign -= 4294967296;

}

return abs($unsign);

}

如此以来,在32位系统占用运行 杠杠的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值