Pythonで文字列のODIN-1を生成する必要があります。公式ドキュメントでは、SHA-1を入力文字列/識別子に適用するように指定されていますが、事前に他の操作を実行する必要があるかどうかわかりませんか?また、最終出力はSHA-1の16進ダイジェストか何か他のものですか?
たとえば、PythonでこのMACをODIN-1に変換するにはどうすればよいですか?「74e2f543d2ce」
前もって感謝します!
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'
リンクしたドキュメントと私の答えの間で、これを1行ずつ分解してみましょう。
// 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";
Pythonの場合:
>>> '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()
正しいハッシュを生成します(投稿したリンクに従って)。
これが私の答えをより明確にするのに役立つことを願っています。
Pythonで文字列のODIN-1を生成する必要があります。
いいえ、ドキュメントによると、そうではありません。
802.11 MACアドレス、ANDROID_ID、またはDeviceUniqueIDのODIN-1を生成します。いくつかの関連する引用:
シードは、オペレーティングシステムによって返される形式から変更されないままにしておく必要があります。
注:iOSは、チャートのすぐ下にある「文字列ではなく、6バイトの配列」のMACアドレスを返します。
…それを生のバイト配列として表すことで、句読点と大文字化に関するあいまいさを防ぎます。
また、IIRCANDROID_ID
は64ビット整数であり、MACでも文字列でもありません。DeviceUniqueId
( Windows Phoneについてはわかりません。)
[0x74, 0xe2, 0xf5, 0x43, 0xd2, 0xce]
したがって、おそらく、12文字の文字列ではなく、6バイトの配列のODIN-1を生成する必要があります"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'
また、wikiページに投稿された予備仕様の説明を探している場合、そのページにコメントを投稿する代わりに、なぜSOでそれについて質問するのでしょうか。
最初の特定の質問に答えるには:
事前に他の操作を行う必要があるかどうかわかりませんか?
仕様によると:
シードは、オペレーティングシステムによって返される形式から変更されないままにしておく必要があります。
あなたの2番目に答えるには:
また、最終出力はSHA-1の16進ダイジェストか何か他のものですか?
仕様によると:
結果のメッセージダイジェストはODIN-1です。
//このハッシュの形式は、40文字の小文字の文字列である必要があります。
その間、プロジェクトに添付されたサンプルコードがあります(それがgooglecodeにあることを考えると、あなたが期待するように)…しかし、それはそれほど役に立ちません。
iOSサンプルには、関連するコードが完全に含まれていません。これは、ウィザードによって生成された汎用GUIアプリであり、にとが追加さ#import "ODIN.h"
れtextView.text = [ODIN1() lowercaseString];
ていviewDidLoad
ます。しかし、そのODIN.h
ファイル、および対応するODIN.m
orlibODIN.a
または何かがどこにも存在しないように見えます。(を一目見ただけで、project.pbxproj
明らかにもっと多くのファイルがあるはずですが、明らかにチェックインしていませんでした。)
Androidサンプルには関連するコードが含まれていますが、明らかに仕様に違反しています。ANDROID_ID
をUnicode文字列として取得し、それをiso-8859-1にエンコードし、結果のバイトでSHA-1を呼び出し、それから16進ダイジェストを生成します。ドキュメントには、OSから返される値とまったく同じOS値を使用するように明示的に記載されています。コードLatin-1は代わりにそれをエンコードします。
一方、 Windowsサンプルは、ドキュメントに記載されていることを実行しているように見えます。つまり、DeviceUniqueIdをとして取得し、そのままbyte[]
使用します。(ただし、コードは実際には機能しません。これは、廃止されたAPI呼び出しを使用しているため、…を返すのではなく、例外をスローするためbyte[]
です。)
この時点で、そもそもなぜこの仕様に従っているのかを尋ねる必要があります。他の人のコードと相互運用しようとしている場合は、設計者が意図したものを推測するのではなく、この仕様を解釈する矛盾した方法のどれがそのコードで使用されているかを気にするでしょう。
言うまでもなく、AppleはUDIDの代わりにMACに基づくものを使用しないように明示的に指示しており、ODINはUDIDの代わりにMACに基づく自明なものです…</ p>