given some binary / bitstring
<<1,2,3,4,5>>
how do you split it into n
bit chunks.
where n could be 1 bit, 2 bits, etc.
Desired output for 6bits
given above binary in bit form 0000000100000010000000110000010000000101
[<<0::size(6)>>, <<16::size(6)>>, <<8::size(6)>>, <<3::size(6)>>, ...]
The key to this is matching the rest of the binary with rest::bitstring
(instead of rest::binary
), which will also match binaries with partial bytes.
defmodule BitUtils do
def chunks(binary, n) do
do_chunks(binary, n, [])
end
defp do_chunks(binary, n, acc) when bit_size(binary) <= n do
Enum.reverse([binary | acc])
end
defp do_chunks(binary, n, acc) do
<<chunk::size(n), rest::bitstring>> = binary
do_chunks(rest, n, [<<chunk::size(n)>> | acc])
end
end
Usage:
iex> BitUtils.chunks <<1, 2, 3, 4, 5>>, 6
[<<0::size(6)>>, <<16::size(6)>>, <<8::size(6)>>, <<3::size(6)>>,
<<1::size(6)>>, <<0::size(6)>>, <<5::size(4)>>]
A simplest approach is probably to use for
comprehensions with binary generator:
for << chunk::size(6) <- binary >>, do: <<chunk::size(6)>>
We can hide it behind a function
def chunk_bits(binary, n) do
for << chunk::size(n) <- binary >>, do: <<chunk::size(n)>>
end
This gives the desired output:
iex> chunk_bits(<<1, 2, 3, 4, 5>>, 6)
[<<0::size(6)>>, <<16::size(6)>>, <<8::size(6)>>, <<3::size(6)>>,
<<1::size(6)>>, <<0::size(6)>>]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With