1

I have a bitstring of the form bitstring = <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>>. I want to render but poison or Jason doesn't seem to be rendering. What is the best way to render a bitstring in response like this.

Something like this

bits = <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>>
render(conn, "bits.json", bits: bits)
Tanweer
  • 567
  • 1
  • 5
  • 17

2 Answers2

2

If the goal is to encode and then later decode the bitstring, and efficiency of storage is a concern, I'd go with converting the bitstring to a binary using term_to_binary and then encoding it as a base-64 string. This will give you a nice compact representation of the bitstring that can later be decoded.

defmodule A do
  def encode(bitstring) when is_bitstring(bitstring) do
    bitstring |> :erlang.term_to_binary() |> Base.encode64
  end

  def decode(binary) do
    decoded = binary |> Base.decode64!() |> :erlang.binary_to_term([:safe])
    if is_bitstring(decoded), do: decoded, else: nil
  end
end

IO.inspect encoded = A.encode(<<0::220>>)
IO.inspect A.decode(encoded)

Output:

"g00AAAAcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0::size(4)>>

You can pass the output of A.encode to your JSON encoder and call A.decode after decoding using the JSON decoder.

Dogbert
  • 212,659
  • 41
  • 396
  • 397
1

One cannot convert 46 bits into byte array. AFAICT, there are two most natural options here.

One might use the array with a binary representation of the value:

for << <<c::1>> <- <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>> >>, do: c    
#⇒ [0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
#   0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]

or one might use the binary with the above joined:

(for << <<c::1>> <- <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>> >>, do: c)
|> Enum.join()
#⇒ "0100101000000101000001001000001011101110000000"
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160