2012-12-21 54 views
0

我需要在Python中生成一個字符串的ODIN-1。官方documentation指定將SHA-1應用於輸入字符串/標識符,但我不確定是否需要事先對其執行其他操作?另外,SHA-1或其他東西的最終輸出是十六進制摘要?如何在Python中生成ODIN-1

E.g.我如何將這個MAC轉換爲Python中的ODIN-1? 「74e2f543d2ce」

在此先感謝!

回答

1
from hashlib import sha1 

def odin1(mac_addr): 
    """SHA1 hexdigest of hex representaiton of MAC address""" 
    to_hash ''.join([i.decode('hex') for i in mac_addr.split(':')]) 
    return sha1(to_hash).hexdigest() 

>>> odin1('1a:2b:3c:4d:5e:6f') 
'82a53f1222f8781a5063a773231d4a7ee41bdd6f' 

讓我們打破這種下來,通過你鏈接到文檔之間的一行行,我的回答:

// NOTE: iOS returns MAC Address NOT a string, but a 6-byte array. 

// A human readable MAC Address may be represented as the following: 

@"1a:2b:3c:4d:5e:6f"; 
@"1A2B3C4D5E6F"; 

在蟒蛇:

>>> '1A'.decode('hex') == '1a'.decode('hex') 
True 

因此,我們可以將指定的一個字符串(減少「標點符號和大寫字母之間的任何含糊不清」):

>>> mac = "1a:2b:3c:4d:5e:6f".split(':') 
>>> hex_mac = [m.decode('hex') for m in mac] 
>>> hex_mac 
['\x1a', '+', '<', 'M', '^', 'o'] 

我們可以將此列表視爲一個字符串(就像我們使用一個字節數組一樣),以便從SHA1哈希函數中獲得相同的結果。

當然,我們可以接受的MAC地址這種方式:

>>> mac = '1A2B3C4D5E6F' 
>>> hex_chunks = lambda s: [s[i: i+2] for i in range(0, len(s), 2)] 
>>> [m.decode('hex') for m in hex_chunks(mac)] 
['\x1a', '+', '<', 'M', '^', 'o'] 

因此,這將是由我們來正確地統一輸入爲單跨功能的所有可能的形式進行操作。無論如何,我們的功能可以採取以下形式,最終的結果是最重要的:

>>> sha1(''.join(['\x1a', '+', '<', 'M', '^', 'o'])).hexdigest() 

產生正確的散列(根據您發佈的鏈接)。

希望這有助於使我的答案更清晰。

+0

如果這是正確的,文檔錯了。 (這當然是可能的 - 這看起來不像是由行業標準化委員會或任何其他機構挑選的完全透徹的規範)。他們明確地說:「種子應該不受操作返回的格式的影響系統「,」iOS返回的MAC地址不是一個字符串,而是一個6字節的數組「,」將其表示爲原始字節數組可防止標點符號和大寫字母之間的任何歧義「。 – abarnert

+1

我直接去了鏈接上發佈的例子,並保持僵化。如果輸入變化,你還應該如何消耗MAC地址?我將標準化輸入的任務保留到OP。他們可以把我的代碼片段,並滿足他們的需要......他們可能只需要'hashlib'調用幫助。 – Droogans

+0

你是什麼意思,「如果輸入變化,你應該如何消耗MAC地址?」你從iOS獲得一個6字節的原始字節數組。您正好將該原始字節數組傳遞給SHA1。這就是文檔要做的事情,我不明白這是一個問題。 – abarnert

1

我需要在Python中生成一個字符串的ODIN-1。

不,你沒有,不是根據文檔。

您生成802.11 MAC地址,ANDROID_ID或DeviceUniqueID的ODIN-1。一些相關的報價:

種子應該保持不變從操作系統返回的格式。

注:iOS的返回MAC地址不是字符串,而是一個6字節的數組」的圖表的正下方

...表示它作爲原始字節陣列防止周圍標點符號和大小寫任何模糊:

而且IIRC,ANDROID_ID是一個64位整數,既不是MAC,也不是一個字符串。(我不上Windows Phone的瞭解DeviceUniqueId

所以,你可能需要產生的奧丁-1 6字節的數組[0x74, 0xe2, 0xf5, 0x43, 0xd2, 0xce],不是12個字符的字符串"74e2f543d2ce"。該示例顯示瞭如何在Objective-C中執行此操作;在Python,它是:

mac = bytes([0x74, 0xe2, 0xf5, 0x43, 0xd2, 0xce]) 

或者,因爲你的問題指定的Android,想必你不想要的MAC地址在所有,任何格式......但我認爲這僅僅是一個錯誤的標籤,你'重新使用iOS,想要MAC地址。

你是怎麼做的?

散列步驟:通過SHA-1散列函數傳遞標識符種子。

在Python,這就是:

hash = hashlib.sha1(mac) 

將所得的消息摘要是ODIN-1。

在Python,這就是:

digest = hash.hexdigest() 

將其組合在一起:

hashlib.sha1(bytes([0x74, 0xe2, 0xf5, 0x43, 0xd2, 0xce])).hexdigest() 

結果是 「40小寫字母串」,就如同文檔說應該是:

'10f4ab0775380aceaca5a2733604efa6d6364b08' 

此外,如果您正在尋找初步說明nary spec發佈在wiki頁面上,爲什麼你會在SO上提問,而不是在該頁面上發表評論?

要回答你的第一個具體問題:

我不知道我是否需要事先進行其他的操作呢?

細則中指出:

種子應留有從操作系統返回的格式不變。

要回答你的第二個:

而且,是最終輸出的十六進制的SHA-1的摘要或其他什麼東西?

的規範說:

將所得的消息摘要是ODIN-1。

//這個哈希的格式應該是40小寫字符串:

同時,還有附加到項目的示例代碼(如你所期望的,因爲它在googlecode上)... ...但它的沒有幫助。

iOS sample完全缺少相關的代碼。它是由嚮導生成的通用GUI應用程序,在viewDidLoad中增加了#import "ODIN.h"textView.text = [ODIN1() lowercaseString];。但是那ODIN.h文件,以及相應的ODIN.mlibODIN.a或任何看起來不在任何地方。 (從簡要的一瞥project.pbxproj,顯然應該有更多的文件,他們顯然只是沒有檢查。)

Android sample確實有相關的代碼,但它明顯違反規範。它將ANDROID_ID作爲一個Unicode字符串,然後將其編碼爲iso-8859-1,在結果字節上調用SHA-1,並從中生成十六進制摘要。這些文檔明確指出要使用操作系統返回的操作系統值;代碼Latin-1將其編碼。

另一方面,Windows sample確實看起來像文檔所說的那樣 - 它將DeviceUniqueId作爲byte[],並按原樣使用它。 (但是,代碼實際上不會工作,因爲它使用的是過時的API調用,它會拋出異常而不是返回byte[] ...)

此時,我必須問爲什麼您要遵循此規範第一個地方。如果你試圖與別人的代碼進行互操作,你可能會關心解釋這個規範的矛盾方式是由那個代碼使用的,而不是試圖猜測設計者想要的是哪一個。

更何況,蘋果已經明確地告訴人們不要使用基於MAC東西來代替UDID,並ODIN是一些平凡基於MAC來代替UDID ...

+0

誰低估,謹慎解釋爲什麼? – abarnert

+0

我沒有。我的確看過你的答案,這些答案揭示了我在迴應中掩蓋的細節。我會把它放回給你。 – Droogans

+0

@Droogans:我沒有指責_you_ downvoting;我不知道是誰做的。 SO的工作方式就是這樣。我正在問爲什麼有人這樣做,所以我可以適當地改進答案。 – abarnert