# Stable hashing across Julia versions

**URL:** https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423
**Category:** General Usage
**Created:** [August 4, 2020, 11:33pm UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423 "2020-08-04T23:33:14Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [August 4, 2020, 11:33pm UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/1 "2020-08-04T23:33:14Z")

</div>

Did something change with respect to hashing since 1.4.2? I have code that checks whether data have already been computed by checking a hash of the arguments used to compute the data, and I appear to be getting different hash values in 1.5.0 compared to 1.4.2.

---

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [August 5, 2020, 12:05am UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/2 "2020-08-05T00:05:12Z")

</div>

Perhaps related to [this](https://github.com/JuliaLang/julia/commit/7c45addfe19c63e16a9e936131189d1c22c2b620), since the change seems to related to hashing arrays.

In 1.4.2:

```julia
julia> hash([1,2,3])
0xecc5186e7be222c6

julia> hash.([1,2,3])
3-element Array{UInt64,1}:
 0x02011ce34bce797f
 0x5a94851fb48a6e05
 0x3688cf5d48899fa6

```

In 1.5.0:

```julia
julia> hash([1,2,3])
0xd22721a98cab7f9d

julia> hash.([1,2,3])
3-element Array{UInt64,1}:
 0x02011ce34bce797f
 0x5a94851fb48a6e05
 0x3688cf5d48899fa6

```

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [August 5, 2020, 1:00am UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/3 "2020-08-05T01:00:04Z")

</div>

Hashing is not guaranteed to be stable across Julia versions.

---

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [August 5, 2020, 1:03am UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/4 "2020-08-05T01:03:33Z")

</div>

That’s a really good point. I guess for my code I’ll just have to stick to 1.4.2 for now and think of a better approach in future versions.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [August 6, 2020, 2:55pm UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/5 "2020-08-06T14:55:22Z")

</div>

If the values are always arrays of ints or something comparable, then you could just use `write` to get a “canonical” binary representation and use CRC32 or SHA to hash that binary data. If the data is more complex, you could use [BSON](https://github.com/JuliaIO/BSON.jl) to serialize it and then hash the resulting BSON data.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 6, 2020, 3:44pm UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/6 "2020-08-06T15:44:09Z")

</div>

> [@StefanKarpinski](#):
>
> If the values are always arrays of ints or something comparable, then you could just use `write` to get a “canonical” binary representation and use CRC32 or SHA to hash that binary data.

You can also do `crc32c(reinterpret(UInt8,a))` (for an array of bitstypes, using the `crc32c` function from the `CRC32c` standard library), rather than `write`. Both `write` an `reinterpret` will lead to an endianness-dependent result, of course (unless you use `hton` or similar first).

---

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [August 7, 2020, 6:27am UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/7 "2020-08-07T06:27:20Z")

</div>

Thanks to both of you! Those are interesting solutions and I’ll probably try out both and see what works. This actually also helps me with a related question I posed here a while back, that is how to make a hash that works both for julia and Python.

---

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [September 23, 2020, 2:22am UTC](https://discourse.julialang.org/t/stable-hashing-across-julia-versions/44423/8 "2020-09-23T02:22:57Z")

</div>

Because I had a lot of data already stored using hash values from julia-1.4, I decided to pull out the hashing code from julia base, preserving its state at v1.4.2, and put it into a separate repository [StableHashes](https://github.com/grero/Stables%5CHashes.jl.git). From here I export the function `shash` which basically does (mostly) whatever the `hash` function did in 1.4.2. Since this code was copied directly from the julia repository, please let me know if that is in any way problematic. I’ve kept the MIT license from julia, obviously, and I’ve kept all comments about the origin of the code.
