由网络副手--寻路人于2016.10.14 17:31:12发布在PHP代码 PHP 中CRC32 在32位系统和64位系统中的坑 阅读4083 评论0 喜欢2 很多小伙伴在对字符串进行取模或者做指纹存储的时候用到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位系统占用运行 杠杠的. 赞 2 分享 赏 您可以选择一种方式赞助本站 支付宝扫码赞助 BraveDu 署名: 网络副手~寻路人