Wednesday, March 6, 2013

[python] md5 與數字 hash

python新手上路,寫點東西記錄一下以免自己忘記。

這次剛好有個需求是需要給金流一個流水號,但是由於cassandra設計上沒辦法像mssql有@@IDENTITY這種方便的取識別值方式,所以只好自己想辦法了,原本想說要找zookeeper或是snowflake這些分散式系統取流水號的方式,但是因為時間因素沒辦法研究這些東西,只好先想個方法硬上。

由於spec上的規格是九位的數字,所以研究了一下,決定將key值拿來md5後的hash轉成int,再取九碼出來(原本會是大約38~40位的數字),原則上在短時間內是不會遇到重複的情況,然後只要每次產生數字hash後,先確認cassandra內有沒有這個number hash,沒有的話再使用,有的話就重生一個;由於理論上這個number hash會發生一次重複的時間應該遠比cassandra最終同步的時間來的長,所以會遇到丟出重複流水號的機會可說是微乎其微,在有更好的解法之前這個方式應該可以加減用。

語法很簡單,大概就是這樣
import hashlib
def md5(istr):
    return hashlib.md5(istr).hexdigest()

def randNum(istr):
    return str(int(md5(istr),16))[:9]
print md5('test')
//098f6bcd4621d373cade4e832627b4f6
print randNum('test')
//1270773689

跑起來結果就是這樣,不過下圖測試時我是取十位XD

Python_hash

小小記錄一下心得。

update一下,如果要取一個不到20位的數字,可以使用這個方式,str(uuid.uuid4().get_time())會回傳一個約19位的數字字串,我不曉得他會不會長到20,不過看來是可以用的,而且又不是亂數,剛好符合另一個需求,可賀可喜。

a=uuid.uuid4()
print(a)
//38015b71-d95a-4bd4-a1d2-f1d30bb165d2
print str(a.get_time())[:20]
//852545210989763441

No comments:

Post a Comment