如何将二进制文件拆分为 N 位块

Kei*_*las 3 elixir

给定一些二进制/位串

<<1,2,3,4,5>>
Run Code Online (Sandbox Code Playgroud)

你怎么把它分成n几块。

其中 n 可以是 1 位、2 位等。

所需的 6 位输出

以位形式给出上述二进制 00000001000000100000001100000010000000101

[<<0::size(6)>>, <<16::size(6)>>, <<8::size(6)>>, <<3::size(6)>>, ...]
Run Code Online (Sandbox Code Playgroud)

Pat*_*ity 6

关键是将二进制文件的其余部分与rest::bitstring(而不是rest::binary) 进行匹配,这也将匹配具有部分字节的二进制文件。

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
Run Code Online (Sandbox Code Playgroud)

用法:

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)>>]
Run Code Online (Sandbox Code Playgroud)


mic*_*ala 5

最简单的方法可能是使用for带有二进制生成器的推导式:

for << chunk::size(6) <- binary >>, do: <<chunk::size(6)>>
Run Code Online (Sandbox Code Playgroud)

我们可以把它隐藏在一个函数后面

def chunk_bits(binary, n) do
  for << chunk::size(n) <- binary >>, do: <<chunk::size(n)>>
end
Run Code Online (Sandbox Code Playgroud)

这给出了所需的输出:

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)>>]
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果最后一个块小于 `n` 位,这将跳过最后一个块:`for &lt;&lt;chunk::size(16) &lt;- "a"&gt;&gt;, do: &lt;&lt;chunk::size(16)&gt;&gt; # =&gt; []`。 (5认同)