是否有任何快速算法可以存储包含L位1的所有各种N位数?提供N和L参数。它是在课堂上破解加密系统的,我注意到有两个定时攻击,我可以找到比特长度(N)和1比特(L)的数量。
而不是强制降低下限和上限之间的所有值,而是最小化我需要测试的元素。因此,我正在考虑使用一个包含所有元素的向量,它可能适合我从2个定时攻击中获得的信息。
任何提示都将非常感激。
我正在使用C ++。
答案 0 :(得分:4)
Bit Twiddling Hacks页面显示了如何使用每个生成的数字的O(1)工作枚举正好n位设置的所有二进制数。他们的解决方案在此重印:
假设我们在整数中有一个N位设置为1的模式,我们想要 字典意义上的N 1位的下一个排列。对于 例如,如果N为3且位模式为00010011,则为下一个模式 将是00010101,00010110,00011001,00011010,00011100,00100011, 等等。以下是计算下一个的快速方法 排列。
unsigned int v; // current permutation of bits unsigned int w; // next permutation of bits unsigned int t = v | (v - 1); // t gets v's least significant 0 bits set to 1 // Next set to 1 the most significant bit to change, // set to 0 the least significant ones, and add the necessary 1 bits. w = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
x86 CPU的
__builtin_ctz(v)
GNU C编译器内在函数返回尾随零的数量。如果您使用Microsoft编译器 x86,内在为_BitScanForward
。这些都发出一个bsf 指令,但其他架构可能有等效的指令。 如果没有,那么考虑使用其中一种方法来计算 前面提到的连续零位。这是另一个版本 由于它的除法运算符,它往往会变慢,但事实并非如此 要求计算尾随零。unsigned int t = (v | (v - 1)) + 1; w = t | ((((t & -t) / (v & -v)) >> 1) - 1);
从除了最后L位(全1)之外的所有0的数字开始,你应该能够使用它来枚举你想要的所有数字。
希望这有帮助!
答案 1 :(得分:2)
该死的... templatetypedef得到的答案可能比我的好。我写了一个递归算法来生成它们。可能不是你想要的方式,但似乎有效(免责声明:最低限度的测试!)。
我会留在这里为后代,即使它可能不是实现这一目标的最佳方式。与其他答案不同,这个答案将为您提供包含所有可能组合的向量。显然,如果你有数百万/数十亿的组合,这不是一个理想的方法!但是,我想写一个算法来做这件事很有趣。所以任务完成了。
#include <bitset>
#include <vector>
using namespace std;
const int N = 4;
void addValues(int to_add, int start_pos, bitset<N> const& working, vector<bitset<N>>& values)
{
// Take all of our possible spots
for (int i = start_pos; i < N && i <= N - to_add; ++i) {
auto working_copy(working);
working_copy[i] = 1;
// We have more bits to set...
if (to_add > 1) {
addValues(to_add - 1, i + 1, working_copy, values);
}
// We've set all the bits, so this is a working combination
else {
values.push_back(working_copy);
}
}
}
int main(int argc, char* argv)
{
int L = 2;
vector<bitset<N>> values;
bitset<N> working;
addValues(L, 0, working, values);
return EXIT_SUCCESS;
}