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

Hashes module produces different results in C and JS. #423

Open
treeform opened this issue Aug 20, 2019 · 11 comments
Open

Hashes module produces different results in C and JS. #423

treeform opened this issue Aug 20, 2019 · 11 comments

Comments

@treeform
Copy link

Running this code produces different results in C and JS:

echo hash(123)
echo hash(123.457)
echo hash("hi there")

in C:

123
4638458299730989416
-8297432703265153370

in JS:

123
124.457
1638780415

Should hashing be consistent across compiler backends?

@dom96
Copy link
Contributor

dom96 commented Aug 20, 2019

yeah, it probably should be. I ended up using this in my program:

{.push overflowChecks: off.}
proc customHash*(x: string): int32 =
  ## JS/C backend-compatible hashing
  ##
  ## Initially based on https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0
  ## but JS strings are UTF16...

  for i in 0 ..< x.len:
    result = (31*result + ord(x[i]).int32) or 0

    # echo(result, " ", x[i], " ", ord(x[i]))

{.pop.}

@treeform
Copy link
Author

How did you hash floats?

@dom96
Copy link
Contributor

dom96 commented Aug 20, 2019

Haven't needed that so far, but if you search around for a JS implementation you should be able to find something :)

@andreaferretti
Copy link

It's especially bizarre that hashing a float does not return an int! Moreover, it is not that good of a hash if hash(123.457) == 124.457 :-/

@Araq
Copy link
Member

Araq commented Aug 22, 2019

@andreaferretti This + 1.0 in the hashing logic was stolen from Lua's implementation where it was used this way in production for over a decade. I'm sure we can do better now but it was not done carelessly.

@andreaferretti
Copy link

I wonder what is the rationale for this

@mratsim
Copy link
Collaborator

mratsim commented Aug 23, 2019

What are your use-cases to have the same hashes in C and JS (and I guess the VM)?

@Araq
Copy link
Member

Araq commented Aug 23, 2019

@andreaferretti Normalizing -0.0 to +0.0 (which should compare equal and hence hash equally).

@treeform
Copy link
Author

@mratsim I want to make sure that the data structure I am synchronizing is the same on the server and browser. I wanted to hash both sides and if hash is different there is a desync bug some place.

@krux02
Copy link
Contributor

krux02 commented Aug 30, 2019

The problem for the different Hash results is Here:
https://github.com/nim-lang/Nim/blob/2a3b0563141f2cfdee4cbeef85167c25610ff71f/lib/pure/hashes.nim#L146
This is technically only correct on 64 bit native target.

@Araq
Copy link
Member

Araq commented Sep 2, 2019

@treeform That is a bad idea because then the details are tied to a very specific unspecificied hash algorithm that the stdlib happens to use.

@ringabout ringabout transferred this issue from nim-lang/Nim Sep 5, 2021
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

6 participants