7

这是我正在尝试为其创建最佳解决方案的问题。我在[0...N]范围内有一组有限的非负整数。我需要能够将这个集合中的每个数字表示为一个字符串,并且能够将这样的字符串向后转换为原始数字。所以这应该是一个双射函数。

附加要求是:

  1. 数字的字符串表示应该至少在某种程度上混淆原始数字。所以像f(x) = x.toString()这样的原始解决方案将不起作用。
  2. 字符串长度很重要:越少越好。
  3. 如果有人知道K的字符串表示,我希望它是非平凡的(在某种程度上)猜测K+1的字符串表示。

对于 p.1 和 p.2,显而易见的解决方案是使用类似 Base64(或任何适合所有值的 BaseXXX)符号。但是我们能以最少的额外努力适应第 3 页吗?常识告诉我,对于 BaseXXX 值,我还需要一个双射“String <-> String”函数。有什么建议么?或者也许有比 BaseXXX 更好的东西来满足所有 3 个要求?

4

5 回答 5

1

构造一个长度表M。此表应将数字 0M-1到具有随机顺序的不同短字符串映射。将整数表示为M基数,使用表中的字符串表示数字中的数字。直接反转解码。

使用M=26,您可以只为每个数字使用一个字母。或者M=256为每个数字取一个字节。

甚至不是一个好的加密方法!

于 2012-01-12T11:37:09.013 回答
1

此方法满足要求 1-3,但计算量可能有点过于昂贵:

  1. 找到一个质数p > N+2,不要太大
  2. 找到一个原始根 gp,即乘法阶模pp-1
  3. 对于0 <= k <= N, 让enc(k) = min {j > 0 : g^j == (k+2) (mod p)}
  4. f(k) = enc(k).toString()
于 2012-01-12T11:23:05.410 回答
1

如果您不需要安全,您可以在 BaseXXX 中编码后使用简单的对称密码。例如,您可以选择整数 [n₁, n₂, n₃...] 的密钥序列,然后使用Vigenere cipher

密码背后的基本思想很简单——将每个字符 C 编码为 C + K (mod 26),其中 K 是密钥中的一个元素。随着您的进行,只需从键中获取下一个字符的下一个数字,一旦您用完键中的值,就回绕。

您在这里确实有两个选择:您可以先将数字转换为 baseXXX 中的字符串然后加密,或者您可以使用相同的想法将每个数字加密为单个字符。在这种情况下,您可能希望将其从 更改mod 26mod N + 1

想一想,一个更简单的选择是只xor使用键和值中的元素。(与使用 Vigenere 公式相反。)我认为这同样适用于混淆。

于 2012-01-12T10:10:33.890 回答
0

因此,您需要一个混淆原始数字的字符串,但允许在已知 str(K) 时确定 str(K+1)?

干吗f(x) = (x + a).toString()a秘密在哪里?然后外部用户无法确定xfrom f(x),但他们可以确信如果他们有一个字符串“1234”,例如,对于未知数,x那么“1235”映射到x+1

于 2012-01-12T10:10:03.077 回答
0

页。1 和 p。3有点矛盾,也有点模糊。

我建议使用整数的十六进制表示。

17 => 0x11
123123 => 1E0F3
于 2012-01-12T10:11:44.543 回答