Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRC32 function produces incorrect values by default #18

Closed
alexgorbatchev opened this issue Jan 1, 2022 · 2 comments
Closed

CRC32 function produces incorrect values by default #18

alexgorbatchev opened this issue Jan 1, 2022 · 2 comments

Comments

@alexgorbatchev
Copy link

alexgorbatchev commented Jan 1, 2022

It appears that this library isn't producing expected results out of the box:

const crc32 = require("crc-32")
console.log(crc32.str('SheetJS').toString(16));
>
"-622fc6de"

However:

const crc32 = require("crc-32")
console.log((crc32.str('SheetJS') >>> 0).toString(16));
>
"9dd03922"

Same thing in Ruby:

require 'zlib'
puts(Zlib::crc32('SheetJS').to_s(16))
>
9dd03922

Same thing in Rust:

fn main() {
    let checksum = crc32fast::hash(b"SheetJS");
    println!("{:x}", checksum);
}
>
9dd03922
@alexgorbatchev alexgorbatchev changed the title CRC32 function produces incorrect values CRC32 function produces incorrect values by default Jan 1, 2022
@SheetJSDev
Copy link
Contributor

SheetJSDev commented Jan 1, 2022

A longer response was given in other issues, but to summarize:

  1. They are actually equivalent values, and you can confirm by using >>> 0 to convert to uint32_t and |0 to convert to int32_t:
> CRC32.str("SheetJS")
-1647298270
> CRC32.str("SheetJS") >>> 0
2647669026
> (CRC32.str("SheetJS") >>> 0).toString(16)
'9dd03922'

> 0x9dd03922 | 0
-1647298270
  1. The README notes the convention: https://github.com/SheetJS/js-crc32#usage

The return value is a signed 32-bit integer.

  1. The zlib conventions vary by platform. Python 2.x actually uses the signed values:
$ python --version
Python 2.7.18
$ python -c 'from zlib import crc32; print crc32("SheetJS")' 
-1647298270
  1. Back when we first released the library, V8 "small integer" (Smi) on 64-bit platforms corresponds to 32-bit signed integer (-2**31 to 2**31 - 1). Dealing with 32-bit unsigned integers outside of the range (2**31 to 2**32 - 1) triggered a deoptimization.

@alexgorbatchev
Copy link
Author

Thanks for the follow up, I did read the README more carefully, but unfortunately only after posting the issue. Thank you for the detailed explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants