2012-10-09 229 views
1

我有這種形式的輸入字符串尋找數:產生僞隨機從int

<single char><int starting at 1, going up> 

,並希望產生,每個:

<the same single char><a unique 8 digit number> 

即:

"s1" => "s78138782" 
"t1" => "t18743682" 
"t2" => "t49274876" 

不允許 - 我們已經使用該8位數字:

"t1" => "t78138782" 

這不需要是可逆的,即,我不需要能夠在算法上將「s78138782」轉換回s1。我將它們都保存在數據庫中,以便查找它。我只是想讓這些數字看起來隨機,因爲我逐步加大了t1,t2,t3等等,並且不會重複。

顯然,8個字符的數字會限制我可以擁有的唯一起始字符串的數量:在這個階段,我很好。

任何人都可以給我一個算法嗎?我在Ruby中這樣做,所以Ruby會是理想的,最好使用標準的Ruby/Rails寶石。

+0

只需生成一個隨機數並在其數據庫的字段中放置一個唯一索引。 –

+0

對不起@SergioTulentsev,我不明白。你能解釋一下如何解決我的問題嗎? –

+0

唯一索引解決了重複問題,您將無法插入兩次相同的值。而rand()會照顧隨機性。 –

回答

1

這個問題的一個常見解決方案是可逆的,它是爲數據庫選擇一個隨機加密密鑰,然後對每個輸入字符串進行加密。爲了使目標字符串的大小適當,首先使用不能包含字符串的字符(如空格)填充輸入字符串。

請注意,這個過程是不安全的,但它是僞隨機(或至少,它看起來是隨機的),它避免了任何碰撞的機會。

不幸的是,我不知道紅寶石什麼,但我一起扔在Python這個例子:

import Crypto.Cipher.Blowfish 
import re 
import struct 

parse_id = re.compile("^(\D+)(\d+)$") 
cipher = Crypto.Cipher.Blowfish.new("badsecret", 
            Crypto.Cipher.Blowfish.MODE_ECB) 

def randomize(id): 
    pfx, integer = parse_id.match(id).groups() 
    return "%c%d" % (
    pfx, 
    struct.unpack("!Q", 
        cipher.encrypt(pfx 
        + struct.pack("!Q", 
           int(integer))[len(pfx):]))[0]) 

然後我測試了它:

>>> for i in range(8): print ("t" + str(i), randomize("t" + str(i))) 
... 
('t0', 't8812720357104479300') 
('t1', 't14570648240240394176') 
('t2', 't13775280166960833565') 
('t3', 't6391672674195357485') 
('t4', 't3595757360042384213') 
('t5', 't10728238663553328366') 
('t6', 't888684936954575988') 
('t7', 't9447169127882289438') 
>>> for i in range(8): print ("s" + str(i), randomize("s" + str(i))) 
... 
('s0', 's9209414168426526439') 
('s1', 's5452467189798635654') 
('s2', 's10995755223696930463') 
('s3', 's1237785964853872245') 
('s4', 's4976813073866522017') 
('s5', 's17045636624557288261') 
('s6', 's14217087933089289315') 
('s7', 's3504968071130220057') 

使數字更短,需要找到一個使用較小的塊或使用流密碼來分組密碼。我不知道Ruby在加密庫方面有什麼提供。 (的確,在我編輯這個答案之前,我幾乎不知道Python的加密支持。)

+0

聽起來很有趣,你可以舉一個例子,最好在紅寶石?謝謝! –

+0

@MaxWilliams:恐怕,Python是我能做的最好的。 – rici

+0

太好了,謝謝! –

0

如果你只是在尋找一個僞隨機尋找的數字,我會使用rand()函數生成一個隨機數,並將索引添加到這種隨機數就是你不必擔心碰撞的原因。