# Convert hash digest to UInt256

**URL:** <https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307>\
**Category:** Performance\
**Created:** [April 10, 2022, 3:35pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307 "2022-04-10T15:35:00Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jj-404](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jj-404/32/34532_2.png) [@jj-404](https://discourse.julialang.org/u/jj-404)\
**Post date:** [April 10, 2022, 3:35pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/1 "2022-04-10T15:35:01Z")

</div>

Hello guys,  
I need to convert the output of sha256 to a UInt256. What is the optimal way to do that performance-wise?

```julia
using SHA, BitIntegers
x=sha256("okok")
# convert(UInt256, x)

```

for context, sha256 returns a `Vector{UInt8}`

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [April 10, 2022, 6:28pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/2 "2022-04-10T18:28:55Z")

</div>

Laconically today,

```julia
julia> using BitIntegers

julia> reinterpret(UInt256, rand(UInt8, 64))
2-element reinterpret(UInt256, ::Vector{UInt8}):
 0x1a12ed72cbc1aa4f71e3dd40bd6a1af939664d1cbbc8fa06aa4de57f60da72cd
 0x8350a89b2786c47309bbf6eeb71a21a3dec3bc73aca23396ffc10356223e9570

```

---

<div class="post-metadata">

**Author:** ![jj-404](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jj-404/32/34532_2.png) [@jj-404](https://discourse.julialang.org/u/jj-404)\
**Post date:** [April 10, 2022, 8:12pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/3 "2022-04-10T20:12:50Z")

</div>

Thanks a lot,  
This works `reinterpret(UInt256, x)[1]`

---

<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:** [April 10, 2022, 9:17pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/4 "2022-04-10T21:17:17Z")

</div>

This might not use the byte order you want:

```julia
julia> h = rand(UInt8, 32);

julia> bytes2hex(h)
"b9a868cba886baa10e08c841e8c0eabac34b83de68207c8bad6f2c869bc4a547"

julia> reinterpret(UInt256, h)
1-element reinterpret(UInt256, ::Vector{UInt8}):
 0x47a5c49b862c6fad8b7c2068de834bc3baeac0e841c8080ea1ba86a8cb68a8b9

```

Because the hash is returned in bigendian order, in principle you can use `ntoh(reinterpret(UInt256, h))`.

Currently `ntoh` fails because `bswap` is not implemented for `UInt256`, but that seems like an oversight in the BitIntegers.jl package ([BitIntegers.jl#26](https://github.com/rfourquet/BitIntegers.jl/issues/26)) that could be easily remedied.

---

<div class="post-metadata">

**Author:** ![jj-404](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jj-404/32/34532_2.png) [@jj-404](https://discourse.julialang.org/u/jj-404)\
**Post date:** [April 11, 2022, 2:14pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/5 "2022-04-11T14:14:32Z")

</div>

ah thanks, that saved me lot of debugging time!, also thanks for opening the issue  
not a great solution but in the meantime, this works:

```julia
reinterpret(UInt256, reverse(x))[1]

```

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 12, 2022, 9:17am UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/6 "2022-04-12T09:17:41Z")

</div>

I think I would go with pointer manipulation for speed, and bypass `reinterpret`:

```julia
GC.@preserve x bswap(unsafe_load(Ptr{UInt256}(pointer(x))))

```

---

<div class="post-metadata">

**Author:** ![jj-404](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jj-404/32/34532_2.png) [@jj-404](https://discourse.julialang.org/u/jj-404)\
**Post date:** [April 12, 2022, 7:00pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/7 "2022-04-12T19:00:05Z")

</div>

Really Cool! this is almost 4 times faster,  
would you mind explaining what’s going on here?  
specifically, what does the GC.@preserve, and also is the “unsafe\_load” actually safe to use in all use cases?

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [April 12, 2022, 7:10pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/8 "2022-04-12T19:10:22Z")

</div>

> [@jj-404](#):
>
> what does the `GC.@preserve`

AFAIU [it](https://docs.julialang.org/en/v1/base/base/#Base.GC.@preserve) instructs the GC not to interfere with the `unsafe_load` (otherwise you could end in undefined behavior land) and I’m really unsure if we should recommend this to unsuspecting users…

> [@jj-404](#):
>
> and also is the “unsafe\_load” actually safe to use in all use cases

No, exactly (the problem being it could look like it for a long time;).

If performance is of outermost importance in the meantime, would you propose a MWE?

---

<div class="post-metadata">

**Author:** ![jj-404](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jj-404/32/34532_2.png) [@jj-404](https://discourse.julialang.org/u/jj-404)\
**Post date:** [April 12, 2022, 7:25pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/9 "2022-04-12T19:25:16Z")

</div>

Ahah, that’s what I thought, I read about it and will stick with the other (more julian) option for now, thanks.  
Performance is important in my case, but not at the cost of readability nor unsafeness, and in this example, the hash function takes most of the execution time anyway.  
I also saw that if you put GC.@preserve inside a function and then define it differently, the first definition stays, and it could add some confusion for users.  
my MWE would be the following:

```julia
using BitIntegers, SHA
f(x) = reinterpret(UInt256, reverse(sha256(x)))[1]

```

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [April 12, 2022, 7:49pm UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/10 "2022-04-12T19:49:34Z")

</div>

Nice!

I tried to `tuple` a bit and found this one

```julia
x = sha256("The quick brown fox jumps over the lazy dog")
y = (x...,)
@show typeof(x)
@show reinterpret(UInt256, x)
@show typeof(y)
@show reinterpret(UInt256, y)

```

yielding

```julia
typeof(x) = Vector{UInt8}
reinterpret(UInt256, x) = UInt256[0x92e5c937bfd0022d76db3c6de451568d4f2e08b0bc9aca699480d707b3fba8d7]
typeof(y) = NTuple{32, UInt8}
ERROR: bitcast: expected primitive type value for second argument

```

Reasonable (or in other words: since when is `Vector` primitive)?

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 13, 2022, 8:31am UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/11 "2022-04-13T08:31:00Z")

</div>

> [@jj-404](#):
>
> what does the GC.@preserve, and also is the “unsafe\_load” actually safe to use in all use cases?

`unsafe_load` is safe to use when you know that the pointer points at a valid object; here after obtaining the pointer via `pointer(x)`, `x` might be garbage collected before `unsafe_load` retrieves the value, so `GC.@preserve x ...` makes sure `x` is kept alive for the duration of the expression.

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 13, 2022, 8:37am UTC](https://discourse.julialang.org/t/convert-hash-digest-to-uint256/79307/12 "2022-04-13T08:37:45Z")

</div>

If you want to avoid `unsafe_load`, and if performance is important, you might be better off with

```julia
bswap(reinterpret(UInt256, (x))[1])

```

rather than

```julia
reinterpret(UInt256, reverse(sha256(x)))[1]

```
