【问题标题】:Efficiently generating a random binary number with fixed set bits and known bitwise AND results有效地生成具有固定设置位和已知按位与结果的随机二进制数
【发布时间】:2016-06-15 14:36:10
【问题描述】:

给定 A 中的输入二进制数列表和 B 中的输出二进制数列表,为所有 X 寻找一个满足位与的值。即 A 和 X = B 其中 A 有 6 个设置位,B 有 0 到 6 个设置位,X 有 12 个设置位。 A、B 和 X 中的所有数字都是 128 位长。

与这个问题类似:Most efficient method of generating a random number with a fixed number of bits set 但我还需要该随机数来在与一组已知二进制数进行按位运算时产生已知的二进制结果

一个天真的想法: 生成一个 12 位设置的随机 128 位数字 X,然后针对 A 中的所有数字对其进行测试,看看它是否生成了 B。如果没有,则将X 中的位,然后重试。

我知道一定有更好的算法。

澄清:B 与 A 相同,只是 A 中设置的部分或全部位 (1) 现在已在 B 中随机设置为 0。

更新我的幼稚想法:

我刚刚发现,只要 A 中的某个位为 1,相应的位 X 将等于 B 中的相应位,因为 1 AND xBit = bBit。 当 A 中的位为 0 时,xBit 是未知的(0 或 1)。所以对于每个 A 中的数字,我可以得到由 1、0 和未知 y 组成的字符串 X。 例如yy00011y10010y10... 然后我可以将所有这些字符串 X 与 彼此并通过将 y 替换为 1s 来找到独特 X 的“适合” 和 0。我不确定这是否是最好的方法,但它可能是 比猜测和检查更好。对此有什么想法,或者如何找到合适的?谢谢

【问题讨论】:

  • 嗨@MarcB 这不是作业问题。我正在从事一个涉及一些按位加密/安全模块的项目,这是一个让我卡住的较小组件。我的编程问题是,对于这类事情,是否存在任何类型的算法。如果您可以向我推荐任何类似的东西,我也愿意阅读学术论文。
  • 这是不可能的,除非 A 和 B 已被特别选择以使其成为可能。这是因为AND 操作是严格还原的。考虑A = {'01'}B = {'10'}。不存在 no X 这样的(A and X) = B,不管你让它有多少位。
  • XOR 当然可能是可能的,但我怀疑一般情况下。
  • 感谢@RBarryYoung 的有用评论。在我的项目中,A 和 B 是 128 位数字,随机设置位(B 可能没有设置位,或最多 6 个设置位。A 总是有 6 个)。我需要找出我们的密钥 X 中的哪些位与输入相同,这就是我使用 AND 的原因。不确定 XOR 在这里是否有效,但我可以考虑其他可能解决问题的按位运算。
  • @RBarryYoung 再次阅读您的评论,我应该澄清一下。 B实际上是A,但是A中的一些设置位现在被随机设置为0,而一些设置位未被触及(这就是为什么B有0到6个设置位,而A有所有6个设置)。所以你的例子是A = {'01'}B = {'00'},如果我们需要在X中设置一个1位,我们有X = {'10'}

标签: algorithm optimization random binary bit-manipulation


【解决方案1】:

您可以在Binary Decision Diagram 中编码约束,应用计算机编程艺术第 4A 卷中的算法 C(计算每个 BDD 节点的解数),然后从中生成随机解。

对于每个节点,您可以选择“高”或“低”,具体取决于您选择该变量是 1 还是 0。这两种方式都有一些解决方案,我们称它们为 #H 和 #L。为了随机选择每个解决方案的可能性相同,请选择概率为#H / (#H + #L) 的高(即将此变量设置为 1),选择低的概率为 1 减去该概率。继续这样做,直到您处于接收节点中。这通常会起作用,而不仅仅是这个问题。

BDD 可以通过相交(在 TAOCP 中给出的算法,但当然存在于每个 BDD 库中)一个编码 A & X = B 约束的 BDD 来构造(微不足道 - 只是一个线性 BDD,它强制一些位保持不变并省略所有不受约束的位)具有强制 X 的 popcnt 为 12 的 BDD(这看起来像一个 12 x 128 的节点“网格”,其中附加了一些额外的链,每个额外的设置位都进入底部接收器)。我想总 BDD 也可以立即构建,而不是分两步,但这听起来有点烦人。


也可以更直接的生成非随机解,先放入最多6个强制位:

X = B // assuming A & B = B

然后将剩余的 1 放在“无害”的任何地方,

R = (1 << (12 - popcnt(X))) - 1 // right number of 1's, wrong place
X |= _pdep_u64(R, ~A);

A 没有约束的任何地方都可以,它们从下到上填充,但如果我们不关心随机性,那也没关系。另请注意,我使用了_pdep_u64,而不是_pdep_u128,但这没关系,因为低 64 位总是有空间容纳最多 12 位,A 只有 6 位设置有至少 58 个位置用于剩余位去吧。

【讨论】:

  • 谢谢!我刚刚找到了一个可行的解决方案,但我接受了你的解决方案。我会进一步调查。
【解决方案2】:

我刚刚找到了一个解决方案,从我的更新到上面的幼稚想法

将 X 字符串中的所有未知 y 值设置为 0,然后按位或全部 X 结果得到满足所有的 X 的最终值。

由于我只检查 A 中的 6 位,它可以工作,但在另一种情况下可能无法很好地扩展。

这看起来很简单,我已经在多组上对其进行了测试。它运作良好,但我不确定这是否是最好的方法。

【讨论】:

  • 等等,这样可以吗?显然比我的想法简单得多,但我认为结果应该从一组解决方案中统一选择
  • 不,整个批次的输入和输出的结果 X 是相同的。它必须是一个满足所有 AND 运算的二进制数。是的,它有效,抱歉,我对解决方案的描述似乎到处都是。
猜你喜欢
  • 1970-01-01
  • 2012-11-29
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多