# BigInt to bytes

**URL:** <https://discourse.julialang.org/t/bigint-to-bytes/91107>\
**Category:** General Usage\
**Created:** [December 1, 2022, 4:39pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107 "2022-12-01T16:39:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![iskyd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iskyd/32/44797_2.png) [@iskyd](https://discourse.julialang.org/u/iskyd)\
**Post date:** [December 1, 2022, 4:39pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/1 "2022-12-01T16:39:31Z")

</div>

I’m looking for a way to convert a BigInt number to bytes representation (in python this is done via (int).to\_bytes()).

The only solution I came up with is doing BigInt → Hex → Bytes.  
For example:

```julia
number::BigInt = parse(BigInt, "100001111001101100000100011100110110101110110110101010100001011100110011000110001100101001111111011111100100110011111101001110101011100111000011010011101100100010000011110011011100011001100110101111101011001111111110111011101110101001000100011001110100011011001010", base=2)
hex2bytes(string(number, base=16))

```

Is there any better approach?  
Other than BigInt → bytes is there any way to just perform binary → bytes so that starting with a binary string I can came up with it’s binary representation in one way?

Thanks.

---

<div class="post-metadata">

**Author:** ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)\
**Post date:** [December 1, 2022, 4:48pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/2 "2022-12-01T16:48:12Z")

</div>

> [@iskyd](#):
>
> ```julia
> number::BigInt = parse(BigInt, "100001111001101100000100011100110110101110110110101010100001011100110011000110001100101001111111011111100100110011111101001110101011100111000011010011101100100010000011110011011100011001100110101111101011001111111110111011101110101001000100011001110100011011001010", base=2)
> 
> ```

```julia
julia> string(number; base=2)
"100001111001101100000100011100110110101110110110101010100001011100110011000110001100101001111111011111100100110011111101001110101011100111000011010011101100100010000011110011011100011001100110101111101011001111111110111011101110101001000100011001110100011011001010"

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 1, 2022, 4:49pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/3 "2022-12-01T16:49:40Z")

</div>

> [@iskyd](#):
>
> I’m looking for a way to convert a BigInt number to bytes representation (in python this is done via (int).to\_bytes()).

Do you mean you want the bytes making up that `BigInt`, so a `Vector{UInt8}`?

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 1, 2022, 5:28pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/4 "2022-12-01T17:28:04Z")

</div>

```julia
digits(UInt8, number; base=256)

```

does the job. It is least significant bytes first. You may want to `reverse(digits(UInt8, number; base=256))` if the other direction is better.

---

<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:** [December 1, 2022, 7:14pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/5 "2022-12-01T19:14:44Z")

</div>

A low-level way to do this is to call the [low-level `mpz_export` function](https://gmplib.org/manual/Integer-Import-and-Export) of GMP:

```julia
function to_bytes(n::BigInt; bigendian::Bool=true)
    bytes = Vector{UInt8}(undef, (Base.GMP.MPZ.sizeinbase(n, 2) + 7) ÷ 8)
    order = bigendian ? Cint(1) : Cint(-1)
    count = Ref{Csize_t}()
    @ccall "libgmp".__gmpz_export(bytes::Ptr{UInt8}, count::Ref{Csize_t}, order::Cint,
                1::Csize_t, 1::Cint, 0::Csize_t, n::Ref{BigInt})::Ptr{UInt8}
    @assert count[] ≤ length(bytes)
    return resize!(bytes, count[])
end

```

This is by far the fastest of the methods discussed so far:

```julia
julia> using BenchmarkTools

julia> n = factorial(big(999));

julia> @btime to_bytes($n, bigendian=true);
  2.120 μs (1 allocation: 1.14 KiB)

julia> @btime hex2bytes(string($n, base=16));
  5.632 μs (3 allocations: 3.39 KiB)

julia> @btime reverse!(digits(UInt8, $n; base=256));
  667.791 μs (10670 allocations: 1.79 MiB)

julia> to_bytes(n, bigendian=true) == reverse!(digits(UInt8, n; base=256))
true

```

(The `digits` function seems terribly slow, probably could be improved?)

Note that the `hex2bytes` method fails if `string(n, base=16)` has an odd number of digits (in which case you need to pad with a zero).

---

<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:** [December 1, 2022, 7:35pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/6 "2022-12-01T19:35:30Z")

</div>

> [@stevengj](#):
>
> (The `digits` function seems terribly slow, probably could be improved?)

Interestingly enough, we already had some discussions of this, resulting in an optimized `digits` for `base ≤ 62` ([faster digits(::BigInt) by stevengj · Pull Request #37075 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/37075)). Seems like we could just add an additional fast path when ~~`base == 256 * sizeof(T)`~~ `ispow2(base) && base-1 ≤ typemax(T)`.

_Update_: pull request submitted ([faster digits(::BigInt, base=2^n) via mpz\_export by stevengj · Pull Request #47774 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/47774))

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [December 1, 2022, 8:22pm UTC](https://discourse.julialang.org/t/bigint-to-bytes/91107/7 "2022-12-01T20:22:38Z")

</div>

`(x+7)÷8` is `cld(x,8)` 🙂
