【发布时间】:2016-02-14 07:26:51
【问题描述】:
假设我有 16 个值的 8 个表:
uint32_t lut[8][16];
我想用这样的值填充这些表,以便组合(添加、eor 等)八个表中的每一个中的一个条目将产生一个唯一的 32 位值 - 与组合任何其他组的结果不同条目。
也就是说,对于随机变量i、j、k、l、m、n、o和p,我想要来自@的唯一结果987654330@ 对于这些变量可以具有的所有不同值。虽然合并操作不一定是加号。
总共有16**8(40 亿)个输入组合,每个组合的结果必须不同。
另外——这是最难的部分——我希望这些条目随机出现。
显而易见的答案是:
uint32_t lut[8][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 /* ... */ },
{ 0x000, 0x100, 0x2000 /* ... */ },
/* ... */
};
我们可以证明它适用于:
for (uint64_t x = 0; x < 0x100000000; x++) {
uint32_t y = 0;
for (int i = 0; i < 8; i++) {
y += lut[i][(x >> (i * 4)) & 15];
}
assert(x == y);
}
但这根本不是随机的!
我可以这样做:
for (int i = 0; i < 8; i++) {
shuffle(lut[i], 16);
}
这有点帮助,但不大。
我最终在上面的例子中做了一堆变换。我可以对组合值执行任何 1:1 线性 变换以使其“更随机”,可以提前对表格元素执行,并且如果我得到与我相同的结果'然后我已经证明了每种可能的组合仍然会产生唯一的值(因为它在转换之前就已经完成了)。
不过,这种方法有一些限制。所以我想知道;是否有另一种方法可以使用给定的约束随机化这些表?
【问题讨论】:
-
为什么不做“逆向操作”呢?选择 8 个随机的 32 位值,然后将它们中的每一个“拆分”到相应索引处的表中。
-
@barakmanos 有 40 亿(16 的 8 次方)可能的表格组合,所以当我通过表格分配 32 位结果时,我必须考虑其部分如何与不同的选择交互来自不同的表条目;我不知道该怎么做。
标签: c permutation discrete-mathematics