如何对数字进行编码,以便微小的更改导致非常不同的编码
本文关键字:编码 非常 数字 | 更新日期: 2023-09-27 18:30:38
我正在用C#工作。 我有一个无符号的 32 位整数i
,它会逐渐递增以响应外部用户控制的事件。 该数字以十六进制形式显示为唯一 ID,以便用户以后能够输入和查找。 我需要i
显示一个非常不同的 8 个字符的字符串,如果它递增或两个整数的值接近(例如,距离<256)。 例如,如果i = 5
和j = 6
则:
string a = Encoded(i); // = "AF293E5B"
string b = Encoded(j); // = "CD2429A4"
这方面的限制是:
- 我不希望字符串在每个增量中如何变化的明显模式。
- 该过程需要可逆,因此如果给定字符串,我可以生成原始数字。
- 对于 32 位无符号整数的整个范围,每个生成的字符串都需要是唯一的,以便两个数字永远不会产生相同的字符串。
- 生成字符串的算法应该相当容易实现和维护编码和解码(可能每个 30 行或更少)。
然而:
- 该算法不需要加密安全。 目标是混淆而不是加密。 数字本身不是秘密,它只需要不明显地是一个递增的数字。
- 如果查看大量递增数字,人类可以辨别字符串如何变化的模式,这没关系。 我只是不希望它们是否"接近"很明显。
认识到最小完美哈希函数满足这些要求,但我无法找到一个可以满足我需求或学习如何推导出一个可以满足要求的函数。
我看过这个问题,虽然它有类似的思路,但我相信我的问题在要求上更加具体和精确。 为该问题给出的答案(截至撰写本文时)引用了 3 个可能实现的链接,但不熟悉 Ruby,我不确定如何获取"obfuscate_id"(第一个链接)的代码,Skipjack 感觉对于我需要的东西(第二个链接)有点矫枉过正(第二个链接),并且 Base64 不使用我感兴趣的字符集(十六进制)。
如果 p 和 q 是共素数,则y = p * x mod q
是可逆的。特别是,mod 2^32 很容易,任何奇数都是 2^32 的互质数。现在17,34,51,...
有点太容易了,但模式对于2^31 < p < 2^32-2^30 (0x8000001-0xBFFFFFFF)
来说不太明显。