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)
5
  • What do you mean by render? JSON doesn't have a binary data type. What's your expected JSON value? Commented Aug 3, 2018 at 11:13
  • So I need to convert into a valid bitstring? How do I convert this into a valid bistring so that it can be parsed again into binary Commented Aug 3, 2018 at 11:31
  • What JSON value are you expecting for this? An array of bytes? or perhaps Base64 encoded string? Commented Aug 3, 2018 at 12:35
  • Array of bytes actually Commented Aug 3, 2018 at 12:48
  • 46 bits cannot be packed into an array of bytes. Commented Aug 3, 2018 at 13:23

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This answer is perfect
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"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.