XOR 在两个数字之间切换,mod 怎么样?

XOR to switch between two numbers, how about mod?

我想找到一个项目的替代索引,并且可以将项目切换回其原始索引。 目前,解决方案并不完美 -

说一个项目的标签原来在index1,我想把它移到index2

所以index2 = (index1 ^ tag) % max_index

如果我想将它移回 index1

index1 = (index2 ^ tag) % max_index

以上等式仅在max_index是2的次方时成立。

例如:

( 15 ^ 123 ) % 64 == 52

( 52 ^ 123 ) % 64 == 15

但是

( 15 ^ 123 ) % 60 == 56

( 56 ^ 123 ) % 60 == 7 (!= 15)

不知道有没有其他的数学运算可以让max_index为任意数


编辑:

我需要使用相同的操作来实现两个索引之间的切换

我的场景是 - 我有一个散列 table 每个桶最多可以存储 4 个项目,并且它只存储一个项目的指纹(比如 8 位)。如果桶满了,我需要在不知道其原始表示的情况下将项目的指纹移动到它的替代位置。移动到替代位置后,可以使用与之前相同的操作将指纹移回其原始位置(因为我不知道指纹当前位置是原始位置还是替代位置)。

现在 - index = (index1 ^ Hash(tag)) % max_index

加法和减法工作正常;如果

index2 = (index1 + tag) % max_index

然后

index1 = (index2 - tag) % max_index

在某些语言中,% 对负数的实现很奇怪;如果这是您的顾虑,您可以使用

index1 = (index2 + max_index - tag) % max_index

避免出现问题。


经过一番思考,我提出以下协议。首先选择你最喜欢的对称分组密码;对密码的限制是:

  • 明文space必须至少有max_index个元素
  • 密文space不应比max_index个元素大太多
  • key space 应该比你的标签 space 大(不是硬性要求)

然后按照以下步骤交换索引:

do { index = encrypt(tag, index); } while(index >= max_index);
do { index = index ^ 1;           } while(index >= max_index);
do { index = decrypt(tag, index); } while(index >= max_index);

如果密文 space 的大小是 c*max_index,这将需要 c 次加密和 c 次解密。您从另一端得到的索引将与开始时的索引相同,概率很小——只有当索引加密为 max_index-1(并且 max_index 为奇数)或加密映射两个时才会发生两个相邻值的相邻值。