2010-12-12 59 views
4

我的號碼範圍爲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/>"); 
    } 

?> 

更新:

下面是IDS生成由於這些問題的答案:

qpOLHk 
NMb84H 
aI740D 
x5urn0 
UsROKn 
hPeb7K 
EcByu7 
1zYVRu 
oWlieR 
LjIFBe 
8G52YB 
v3splY 
SqPMIl 
fNc95I 
Cazws5 
ZxWTPs 
mUjgcP 
JhGDzc 
6E30Wz 

Sweeeeeet :-)

回答

3

您可以將數字1到62放入數組中並對數組進行混洗(例如使用Fisher-Yates shuffle)。然後將數組的索引映射到該單元格的內容(但是,如果使用0索引數組,請注意逐個錯誤)。

爲了確定性使用隨機數發生器的特定種子。

編輯:甲少計算上昂貴的(並且也更容易猜測)的映射是由一些常數相乘,然後計算結果的模62:

result = (input * 37) % 62 

數37僅僅是一個例子。您可以使用任何數字,即coprime至62 - 即除31之外的任何奇數。

+0

這適用於我正在考慮的硬編碼。靜態種子會做,但我擔心它太多的處理,我需要一些簡單的... – BarsMonster 2010-12-12 02:50:40

+0

@BarsMonster:允許多少處理?你認爲這個算法的哪一部分太貴了? – 2010-12-12 02:56:21

+0

這將在解釋型語言中每秒執行10,000次。雖然我看到你的解決方案可能符合性能,但我真的很喜歡output =(input + 35)%62,但更隨意一些。 – BarsMonster 2010-12-12 03:01:15

0

使用RSA。這很容易實現(好吧,取決於語言),這裏是一個worked example

+1

不幸的是,它的輸出是模數大數=>我不明白它是如何將每個值映射到某個其他值而沒有指定範圍內的重複值。 – BarsMonster 2010-12-12 02:51:59

+0

@BarsMonster:你說得對。我沒有看到你需要1-62的輸出。 – Jacob 2010-12-12 02:59:09

1

沿着馬克百斯的評論。找到mod n(例如,n = 62)的x的倒數。

x成爲區間[1, n]中的輸入整數。使用extended Euclidean algorithm找到yt,例如xy + nt = 1 mod n。然後y = x^{-1} mod n