2017-07-05 21 views
1

私はPythonでGoogle OAuthを実装するためにthis awesome answerを追跡しました。このエラーは、この行によってスローされ Google OAuth in Python 3エラー

TypeError: ord() expected string of length 1, but int found 

TypeError: ord() expected a character, but string of length 3 found 

この:

o = ord(h[19]) & 15 

o = ord(str(h[19])) & 15をしようとはしてた私は、Python 3で実行してみましたしかし、私はこのエラーを取得しますPython 3では発生しますが、Python 2では発生しません。これにより、バージョン間でいくつかの型が変更されたと思います。これは、関連するコードです:

def get_hotp_token(secret, intervals_no): 
    key = base64.b32decode(secret) 
    msg = struct.pack(">Q", intervals_no) 
    h = hmac.new(key, msg, hashlib.sha1).digest() 
    o = ord(h[19]) & 15 
    h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000 
    return h 

私はthis questionさんの答えに従うことを試みたが、彼らは助けにはなりませんでした。私がkeyまたはmsgの文字列リテラルを使用していないため、最初の答えは役に立たなかった。これにより、第2の回答者の提案を実装で私の試みだった:

def get_hotp_token(secret, intervals_no): 
    key = base64.b32decode(secret) 
    key_bytes = bytes(key, 'latin-1') 

    msg = struct.pack(">Q", intervals_no) 
    msg_bytes = bytes(msg, 'latin-1') 

    h = hmac.new(key_bytes, msg_bytes, hashlib.sha1).digest() 
    o = ord(h[19]) & 15 
    h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000 
    return h 

このコードはkey_bytes = <...>msg_bytes = <...>にこのエラーを投げた:utf-8の代わりlatin-1を使用して

TypeError: encoding without a string argument 

は同じ結果を持っていました。

I print(key, msg)場合、私は、彼らがバイト状にすでにあることを示唆しており、これを取得:

b'fooooooo37' b'\x00\x00\x00\x00\x02\xfa\x93\x1e' 

印刷msgは、上記... string of length 3 foundエラーを説明します。


ここからどこに行くのかはわかりません。どんな提案/解決策も素晴らしいだろう!

+0

'h [19]'と 'type(h [19])'の値を出力できますか? –

+0

@RakeshAdhikesavan、 'print(h [19]、type(h [19]))=> 112 'です。しかし、 '112'は別のランで異なる数字に変わります(それはすべきです)。 – Dopapp

+0

'ord()'は長さ1の文字を期待します。これはPython 2と3で同じです。Unicodeコードポイントを表す整数をUnicode文字として返します。 –

答えて

1

hmac.new()は、バイト列を返します。 Python 3では、これは整数の配列です。したがって、h[19]は整数です。 ord()を呼び出す代わりに、そのintを使用してください。または、hをstrにデコードします。