如何对数字进行编码,以便微小的变化导致非常不同的编码?
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.prime
和rsa.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
。这个方程有一个整数解,因为p
和q
是互质数并且因为Bezout 的恒等式:en.wikipedia.org/wiki/B%C3%A9zout%27s_identity。简短的回答是......只需找到 mod q
的逆 z = 1/p
。示例:q = 5, p = 2, 1/p = 3
.
看起来我可能已经创建了一个副本,并且那里链接的答案使用了 32 位块密码,但 MSalters 的答案似乎对我有用,所以我会继续接受它。 以上是关于如何对数字进行编码,以便微小的变化导致非常不同的编码?的主要内容,如果未能解决你的问题,请参考以下文章