【问题标题】:Unix command-line tool for randomly shuffling chunks of bytes in a binary file?用于随机打乱二进制文件中的字节块的 Unix 命令行工具?
【发布时间】:2013-12-29 11:55:53
【问题描述】:

有没有一种简单的方法可以随机打乱固定大小的字节块?

我有一个包含许多固定大小字节的大型二进制文件(例如,数百 GB)。我不关心随机性,但想洗牌二进制文件中的两个字节(或者可以是任何固定大小的字节,最多 8 个)元素。有没有办法结合unix核心工具来实现这个目标?如果没有这样的工具,我可能不得不开发一个 C 代码。我想听听人们有什么建议。

【问题讨论】:

  • 随机播放 100GB 文件可能需要 很长 时间...
  • Unix 命令行工具通常专门用于处理文本文件,因此最好的办法可能是编写一个程序来执行此操作。由于大小很大,您可能希望使用内存映射一次只洗一点。
  • 元素的最大长度是多少?例如,它可以是 1 兆字节吗? 1 GB?
  • 最大可以是4字节或8字节。
  • 好吧,在这种情况下,我认为您应该直接生成洗牌文件。你知道很多:1.你事先知道会出现什么块,2.你知道分布是平坦的。这意味着您知道一个块的最大出现计数,并且它是一个小数字(可能适合一个字节)。您可以使用此信息直接生成剩余出现计数表,并从中生成文件,同时减少出现计数。所需的内存仅取决于您使用的可能块的数量。

标签: c unix command-line shuffle


【解决方案1】:

这是一个愚蠢的shell技巧。

  1. 首先,使用xxd 将文件分成两个 2 字节块
  2. 使用shuf 随机播放
  3. 使用 xxd 重新组装文件。

例如。

xxd -p -c 2 input_file | shuf - | xxd -p -r - output_file

我还没有在大文件上测试过它。您可能需要使用中间文件。

或者,您可以像这样使用sort -R

xxd -c 2 in_file |sort -R | cut -d' ' -f 2 | xxd -r -p - out_file

这取决于xxd 输出的偏移量,每行的排序应该不同。

【讨论】:

  • 有些unix没有shuf(我的Mac没有),你可以使用perl -MList::Util='shuffle' -e "print shuffle<>"进行移植。
  • 我发现我通过 brew 在我的 mac 中安装了 coreutils(带有 gshuf)。
  • 如果 input_file 对于这个单行来说太大,你可以预先使用 split 将它分成块,在每个块上运行这个单行,然后以随机顺序加入块.
  • @ronmrdechai:嗯,它是 GNU coreutils 的一部分(xxd 显然是 vim 的一部分)。您也可以将其替换为 sort -R,这实际上可能是一个更好的主意(因为我认为它可以更好地处理大量输入。我认为 shuf 可能会尝试将其全部保存在内存中。)
  • @Hasturkun:GNU coreutils 不附带某些 unix(例如 BSD、OS X)。 sort -R 也不适用于 BSD coreutils。它有时会真的烦人......
【解决方案2】:

考虑到要处理的输入文件的大小,这是一个足够复杂的问题。我不会尝试突破 shell 脚本的限制,最好用 C 或其他语言编写代码。

我不知道有什么工具可以让这变得简单。

【讨论】:

  • 感谢您的评论。
  • +1 真正考虑到问题中概述的约束的唯一答案...
【解决方案3】:

试试:

split -b $CHUNK_SIZE $FILE && find . -name "x*" | perl -MList::Util='shuffle' -e "print shuffle<>" | xargs cat > temp.bin

这会创建大量文件,每个文件大小为$CHUNK_SIZE(或小于,如果总文件大小不除以$CHUNK_SIZE),命名为xaaxabxac等,列出文件,打乱列表并加入它们。

这将占用额外 2 倍的磁盘空间,并且可能不适用于大文件。

【讨论】:

  • 感谢您的建议。
  • 存储开销much超过2x,每个小文件至少占用一个block。那是多少,取决于文件系统,但它永远不会少于 512 字节(+ 元数据)。对于最多 8 个字节的块大小(请参阅问题),您的开销系数至少为 64。不要尝试使用数百 GB!
猜你喜欢
  • 2017-06-07
  • 2012-10-11
  • 2018-02-22
  • 2014-01-10
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-25
  • 1970-01-01
相关资源
最近更新 更多