|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2010-02-17 17:47 UTC] jian at theorchard dot com
Description:
------------
According to bug# 36306, this issue should have been fixed. But I found it not entirely fixed across all platforms.
crc32 is returning an unsigned integer on a 64-bit Linux platform. It does return the signed integer from a 64-bit Windows platform as well as 32-bit Windows/Linux platforms.
I found PHP_INT_SIZE and PHP_INT_MAX constants have different values on that 64-bit Linux server with values 8 and 9223372036854775807 respectively. They are 4 and 2147483647 on other 32-bit platforms and 64-bit Windows platform.
Reproduce code:
---------------
<? echo crc32("884385799717_1_1") . "\n"; ?>
Expected result:
----------------
I expect to see value -676770709 both on 32-bit and 64-bit platforms.
Actual result:
--------------
On 64-bit Linux platform I see 3618196587
On 64-bit Windows platform I see -676770709
On 32-bit platforms I see -676770709
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Nov 04 18:00:01 2025 UTC |
Instead of a plain echo, you can also do: printf("%u", crc32("884385799717_1_1")); that should output the same string on every platform (that is at least 32bit). The reason why it is different on Windows vs. (any other) Unix, is because on Windows even on 64 bit CPUs, "long" (the data type we use for integers) is still only 32bit; on Unices, the "long" type is usually 64 bit on 64 bit CPUs.Thanks Derick. That was much more helpful. Unfortunately, I cannot use unsigned integer as our checksum. It has to be signed. I do in fact have a work around function built to solve this issue. I was just wondering whether this will get fixed in the future or not. Since it's a platform dependent issue, it most likely won't get fixed I think. Below is the function I have posted against the crc32 function as a note. I hope this can help others out. Thanks again. function get_signed_int($in) { $int_max = pow(2, 31)-1; if ($in > $int_max){ $out = $in - $int_max * 2 - 2; } else { $out = $in; } return $out; }Why can't you always use a signed checksum if that is what you want? crc32 simply returns 32 bits. You always get the same 32 bits regardless of the platform. If you want to always represent that as a signed 32-bit integer, then do so. The fact that some platforms have the ability to show those 32 bits without messing up the sign is irrelevant. Just emulate it with something stupidly simple like: $max32 = 2147483648; $crc = crc32("884385799717_1_1"); if($crc>$max32-1) { $crc = $crc-2*$max32; } echo $crc;