skip to Main Content

I’m working on a CRC32 algorithm in JavaScript, which I’m new to.
Everything seems to go well until the last step: XOR the checksum with 0xFFFFFFFF.

1001010100111101101100010001000
 ^ 11111111111111111111111111111111 = -1001010100111101101100010001001

1251924104 ^ 4294967295 = -1251924105

It seems like the negative value is a problem. What can I do to address it?

2

Answers


  1. A bitwise operation in Javascript will coerce a Number into a signed 32-bit integer, with a maximum value of 2^31-1. Your number, 0xFFFFFFFF, is 2^32-1.

    However, it will work fine if you use BigInts instead:

    console.log(0xFFFFFFFF ^ 0)
    
    console.log(String(0xFFFFFFFFn ^ 0n))

    Note: I had to use String() because the stackoverflow console.log function does not appear to handle BigInts.

    Login or Signup to reply.
  2. Most bitwise operators in JavaScript operate on and return their results as signed 32-bit integers (as long as the operands are plain numbers, rather than bigints). There is, however, one operator that does not: the unsigned right-shift operator >>>, which returns an unsigned 32-bit integer.

    You can use an unsigned right-shift of zero to coerce a signed 32-bit integer into an unsigned 32-bit integer:

    console.log(~0);
    console.log(~0 >>> 0);
    
    console.log(1251924104 ^ 0xffffffff);
    console.log((1251924104 ^ 0xffffffff) >>> 0);
    
    // since JS bitwise operators work on 32-bit values,
    // bitwise negation is equivalent to XORing with 0xffffffff
    console.log(~1251924104);
    console.log(~1251924104 >>> 0);

    The >>> operator is supported on engines much older than bigint support, which only appeared in ECMAScript 2020 (ECMA-262 11th Ed.). As such, using >>> instead of bigints will ensure better compatibility.

    In any case, the issue is for the most part cosmetic. Whether the values are interpreted as signed or unsigned integers, the bit patterns resulting from applying a bitwise operator are the same. Therefore it should suffice to apply the unsigned coercion only when displaying results, or before feeding them as operands into arithmetic (non-bitwise) operators, where that interpretation actually matters.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search