如何对数字进行编码,以便微小的变化导致非常不同的编码?

Posted

技术标签:

【中文标题】如何对数字进行编码,以便微小的变化导致非常不同的编码?【英文标题】:How to I encode a number so that small changes result in very different encodings? 【发布时间】:2013-09-13 03:56:27 【问题描述】:

我正在使用 C#。我有一个无符号的 32 位整数 i,它会随着外部用户控制的事件而逐渐递增。该数字以十六进制显示为唯一的 ID,供用户稍后输入和查找。我需要i 来显示一个非常不同的 8 个字符串,如果它增加或两个整数在值上接近(例如,距离 i = 5 和j = 6 那么:

string a = Encoded(i); // = "AF293E5B"
string b = Encoded(j); // = "CD2429A4"

对此的限制是:

    我不希望字符串在每次增量中的变化都有明显的模式。 这个过程需要是可逆的,所以如果给定字符串,我可以生成原始数字。 对于整个 32 位无符号整数范围,每个生成的字符串都必须是唯一的,这样两个数字就不会生成相同的字符串。 生成字符串的算法在编码和解码方面都应该相当容易实现和维护(可能每行 30 行或更少)。

但是:

    算法不需要是密码安全的。目标是混淆而不是加密。数字本身不是秘密,它只是不需要明显是一个递增的数字。 如果查看大量递增的数字,人类可以辨别字符串如何变化的模式,那就没问题了。我只是不想让它们“接近”很明显。

我知道Minimal Perfect Hash Function 满足这些要求,但我无法找到一个能满足我需要的人,或者学习如何推导出一个能满足这些要求的人。

我见过this question,虽然它是类似的路线,但我相信我的问题在其要求上更加具体和精确。该问题的答案(在撰写本文时)引用了可能实现的 3 个链接,但不熟悉 Ruby 我不确定如何获取“obfuscate_id”(第一个链接)的代码,Skipjack 感觉有点矫枉过正对于我需要的东西(第二个链接),并且 Base64 不使用我感兴趣的字符集(十六进制)。

【问题讨论】:

“我不希望字符串在每次增量中的变化有一个明显的模式。” - 好吧,创建你自己的混淆模式显然也不是一个好主意,除非你会大量测试它。您是否尝试过寻找任何可用的库/API? 我见过的唯一库本质上是加密的,通常不能很好地处理像 32 位整数这样小的数字。 32 位块密码可以工作,但对于我需要的东西来说似乎有点过头了,我宁愿自己实现它,因为安全不是问题,我正试图降低外部依赖。 FWIW,“obfuscate_id”使用的实际算法在这里:github.com/namick/scatter_swap/blob/master/lib/scatter_swap/… 谢谢。如果其他答案最终对我不起作用,我会看看是否可以移植它。 @hatch22 如果您不希望它是安全的(即很难反转编码),那么混淆 id 的意义何在?我的意思是什么是“明显的模式”?在这一点上,它变得“不明显”。对我来说,这些模棱两可就是不值得做的原因。如果您需要使解码变得困难,则使其实际上变得困难(即加密安全)。不过,我可能对这些要求很天真。 编辑啊,如果您只是想阻止 JimMischel 的网络抓取示例之类的事情,那么简单的模运算技巧 MSalter 是有意义的。 【参考方案1】:

y = p * x mod q 是可逆的,如果 p 和 q 是互质数。特别是,模 2^32 很容易,任何奇数都是 2^32 的互质数。现在17,34,51,... 有点太容易了,但是2^31 < p < 2^32-2^30 (0x8000001-0xBFFFFFFF) 的模式不太明显。

【讨论】:

这看起来很像 RSA 加密,请查看 stuvel.eu/rsa 以获得纯 Python 实现。核心在rsa.primersa.core,你应该可以按照它来将它转换成C# ;-) 模算术非常接近普通算术。你如何为x 解决y = p*x?两边乘以1/p。在这种情况下,您的域不是实数,而是直到 q-1 的整数。那么1/p 是什么?嗯,它是1/p = z,这样z*p = 1 mod q,对于某个整数k,导致z*p - 1 = kq => z*p - kq = 1。这个方程有一个整数解,因为pq 是互质数并且因为Bezout 的恒等式:en.wikipedia.org/wiki/B%C3%A9zout%27s_identity。简短的回答是......只需找到 mod q 的逆 z = 1/p。示例:q = 5, p = 2, 1/p = 3. 看起来我可能已经创建了一个副本,并且那里链接的答案使用了 32 位块密码,但 MSalters 的答案似乎对我有用,所以我会继续接受它。

以上是关于如何对数字进行编码,以便微小的变化导致非常不同的编码?的主要内容,如果未能解决你的问题,请参考以下文章

为啥啁啾频率的微小变化会导致快速傅里叶变换输出发生重大变化?

关于DFS一点微小想法

最佳实践:软件版本控制 [关闭]

对 SQL SERVER 查询的微小更改会导致执行时间极慢

如何始终如一地对具有变化值的数据帧进行热编码?

Python2 编码问题分析