0

When I do a crc32 call on a 32 bit PHP system (PHP_INT_SIZE is 4), the resulting integer value can be negative. How can I get the correct modulo value from the number, regardless if I am on a 32 or 64 bit system?

function checksumChar($str) {
    if(PHP_INT_SIZE > 4) {
        return crc32($str) % 26;
    } else {
        // ???
    }
}
chiborg
  • 26,978
  • 14
  • 97
  • 115
  • The problem is the potential negative number? You could simply call abs() on the resulting crc32() number and then take the reminder. – senex Sep 22 '17 at 15:44
  • @AlexHG The problem with `abs` is that this would give different return values on 32 and 64 bit systems since, for example, `-137262718` and `4157704578` are the same result for `crc32("Hello")`, but are different numbers with different modulos. – chiborg Sep 22 '17 at 16:04

2 Answers2

1

If the result is negative, add 22. (22 is 232 mod 26.) If it's still negative, add 26. This will work regardless of the integer size. If the integer size is 64, then the result will never be negative.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
0

One possible solution would be to generate a hexadecimal value, convert the hex value as a decimal float and use fmod.

function checksumChar($str) {
    if(PHP_INT_SIZE > 4) {
        return crc32($str) % 26;
    } else {
        $hexCRC = (hash('crc32', $str);
        $floatCRC = (float) base_convert($hexCRC, 16, 10);
        return (int) fmod($floatCRC, 26);
    }
}

It's ugly as hell but seems to work. I hope there is a better way ...

chiborg
  • 26,978
  • 14
  • 97
  • 115