I am writing functions that would convert Array{UInt8,1} to BigInt and vice versa.
- From BigInt to Array I use to do as follows, through an hexadecimal string.
function int2bytes(x::Integer)
hex = string(x, base=16)
if mod(length(hex), 2) != 0
hex = string("0", hex)
end
return hex2bytes(hex)
end
@gdkrmr suggested the following faster implementation which I am now using.
function int2bytes(x::BigInt)
result = Array{UInt8}(undef, x.size * sizeof(eltype(x.d)))
unsafe_copyto!(convert(Ptr{eltype(x.d)}, pointer(result)), x.d, x.size)
if ENDIAN_BOM == 0x04030201
result = result[end:-1:1]
end
i = findfirst(x -> x != 0x00, result)
result[i:end]
end
- From Array to BigInt, I am also going through hexadecimal string at the moment.
function bytes2int(x::Array{UInt8,1})
hex = bytes2hex(x)
return parse(BigInt, hex, base=16)
end
Based on @gdkrmr suggestion I am now trying to implement this conversion without string but can’t make it work… I came up with the below code which works when broken down in REPL but crashes when running it in a function.
function bytes2int_new(x::Array{UInt8,1})
l = length(x)
if Sys.WORD_SIZE == 64
T = UInt64
xsize = cld(l, 8)
elseif Sys.WORD_SIZE == 32
T = UInt32
xsize = cld(l, 4)
end
x = cat(fill(UInt8(0), xsize * 8 - l), x; dims=1)
if ENDIAN_BOM == 0x04030201
reverse!(x)
end
if xsize == 1
return reinterpret(T,x)
else
result = big(0)
unsafe_copyto!(result.d, convert(Ptr{T}, pointer(x)), xsize)
result.size = xsize
result.alloc = xsize + 1
return result
end
end
Clearly, there is something I do not understand about pointers and BigInt implementation…
First of all, is it at all possible to create a BigInt by assigning value to its fields?
How to properly assign those value?
What does the alloc field represent?
I may also be on a wrong path for this function, so any suggestions to avoid string representation is welcome for this function