重新排序号码
我的数字范围为 1-62 我希望能够“加密”它们,这样就很难猜测它们是按某种顺序生成的。
所以,它应该是一些映射,例如
1->35 2->19 3->61 ...
这样我就有了 1 对 1 的映射,100% 可逆。
我可以对映射进行硬编码,但我更喜欢数学解决方案,即某种以数字作为参数的公式,并生成 1-62 范围内的数字,并且不会生成重复项。这个公式有可能存在吗?
仅用于历史记录,验证脚本:
<?
$test = array();
$val = 37;
for($i=0;$i<62;$i++)
{
if($test[($i*$val)%62])
{
print("Collision: $i ".$test[($i*$val)%62]."<br/>");
}
$test[($i*$val)%62] = $i;
print("$i => ".(($i*$val)%62)."<br/>");
}
?>
更新:
以下是由于这些答案而生成的 ID:
qpOLHk
NMb84H
aI740D
x5urn0
UsROKn
hPeb7K
EcByu7
1zYVRu
oWlieR
LjIFBe
8G52YB
v3splY
SqPMIl
fNc95I
Cazws5
ZxWTPs
mUjgcP
JhGDzc
6E30Wz
Sweeeeeet :-)
I have numbers in range 1-62
I want to be able to "crypt" them, so that it's hard to guess they are generated in some order.
So, it should be some mapping, for example
1->35
2->19
3->61
...
so that I have 1 to 1 mapping, 100% reversible.
I can hardcode mapping, but I would prefer math solution to that, some kind of formula which takes number as argument, and produces number in range 1-62, and does NOT generate duplicates. Is there any chance this formula exists?
Just for history, validation script:
<?
$test = array();
$val = 37;
for($i=0;$i<62;$i++)
{
if($test[($i*$val)%62])
{
print("Collision: $i ".$test[($i*$val)%62]."<br/>");
}
$test[($i*$val)%62] = $i;
print("$i => ".(($i*$val)%62)."<br/>");
}
?>
Update:
Here are IDs generated thanks to these answers:
qpOLHk
NMb84H
aI740D
x5urn0
UsROKn
hPeb7K
EcByu7
1zYVRu
oWlieR
LjIFBe
8G52YB
v3splY
SqPMIl
fNc95I
Cazws5
ZxWTPs
mUjgcP
JhGDzc
6E30Wz
Sweeeeeet :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以将数字 1 到 62 放入数组中并随机排列数组(例如使用 费舍尔-耶茨洗牌)。然后,数组的索引将映射到该单元格的内容(但如果使用 0 索引数组,请注意差一错误)。
为了使其具有确定性,请使用随机数生成器的特定种子。
编辑:一种计算成本较低(也更容易猜测)的映射是乘以某个常数,然后计算结果模 62:
数字 37 只是一个例子。您可以使用 coprime 到 62 之间的任何数字 - 即除 31 之外的任何奇数。
You could put the numbers 1 to 62 in an array and shuffle the array (for example using the Fisher-Yates shuffle). The index of the array is then mapped to the content of that cell (but be careful of the off-by-one error if you use 0-indexed arrays).
To make it deterministic use a particular seed for the random number generator.
Edit: A less computationally expensive (and also easier to guess) mapping is to multiply by some constant and then calculate the result modulo 62:
The number 37 is just an example. You can use any number that is coprime to 62 - that is any odd number apart from 31.
沿着马克·拜尔斯的评论。求
x
mod n 的倒数(例如,n=62)。令
x
为区间[1, n]
中的输入整数。使用扩展欧几里得算法来查找y
和t< /code> 使得
xy + nt = 1 mod n
。然后y = x^{-1} mod n
。Along the lines of Mark Byers's comment. Find the inverse of
x
mod n (e.g., n=62).Let
x
be your input integer in the interval[1, n]
. Use the extended Euclidean algorithm to findy
andt
such thatxy + nt = 1 mod n
. Theny = x^{-1} mod n
.看看 查看此评论 ="http://php.net/manual/en/function.str-rot13.php" rel="nofollow">
str_rot13()
手册页。Take a look at this comment on the
str_rot13()
manual page.使用 RSA。它很容易实现(嗯,取决于语言),这里有一个工作示例。
Use RSA. It's quite easy to implement (well, depends on the language) and here's a worked example.