Hash(1) change between 1.5 and 1.6

Hi all, I’m trying to recreate the Hash(1) value from Julia 1.1 in our Julia 1.6 codebase.

Hash(1) Julia 1.5: 0x02011ce34bce797f
Hash(1) Julia 1.6: 0x5bca7c69b794f8ce

I’ve delved deep into the c code, without a lot of success. Maybe someone who understands it better than me can advise: What code is required to create a J1.5 Hash function so we can produce the same hashes in J1.6?

The hashing.c file doesn’t appear to have any material changes between the two versions
release-1.1/src/support/hashing.c and release-1.6/src/support/hashing.c

Thanks in advance!

This isn’t in c code — it’s all Julia. So you want to look at hashing.jl and not hashing.c. Here’s the change:

https://github.com/JuliaLang/julia/pull/38031

Fortunately, this also makes it really easy to get the old behavior back:

julia> hash(1)
0x5bca7c69b794f8ce

julia> hx(a::UInt64, h::UInt) = Base.hash_uint64((3a + reinterpret(UInt64,Float64(a))) - h)
hx (generic function with 1 method)

julia> hx(x::Int64) = hx(UInt64(x), UInt(0))
hx (generic function with 2 methods)

julia> hx(1)
0x02011ce34bce797f
2 Likes

I knew I should have just posted here first. Spent all day on this.

Oh well, thanks!

Just for the future, I identified this by just looking at @less hash(1, UInt(0)) on both 1.1 and 1.7. From there it’s pretty easy to see how the codepaths diverge and — fortunately! — Base.hash_uint64 still exists on 1.7 so it’s a short one-liner. Even if it didn’t, though, you could’ve just grabbed its old definition.

1 Like

Super useful - I had no idea about the @less macro.

I also need to make the code work for tuples hash((1,2,3)) on 1.7 but I should be able to do that myself via @less

Thanks again

Unfortunately stuck again, as my code below I adapted

hash_J11(@nospecialize(a), h::UInt) = Base.hash_uint64((3a + reinterpret(UInt64,Float64(a))) - h)

doesn’t like the reinterpret of tuple types:
e.g.
hash_J11((1,"2"), UInt(0))

image

Note that in general, you shouldn’t expect hash to be stable across versions. If you want a stable hash, you shouldn’t use Base.hash.

3 Likes

Yes - i’m aware of that. I’m not complaining about the hash changing, I’m just attempting to re-create the code that existed under J1.1 in order to attain the same hash.

1 Like