Skip to content

Instantly share code, notes, and snippets.

@kaidiren
Last active December 31, 2015 00:29
Show Gist options
  • Save kaidiren/7907585 to your computer and use it in GitHub Desktop.
Save kaidiren/7907585 to your computer and use it in GitHub Desktop.
Google Authenticator code check (just use for check the code) 谷歌身份验证器上产生的代码验证。不用于产生验证码,只进行验证码验证。
# -*- coding:utf-8 -*-
'''
python 2.7
quote from the next url
https://github.com/yurri/py3_google_authenticator/blob/master/google_authenticator.py (python3.X)
大部分的代码都来自与上边的一个url。
由于不需要全部的功能,而且是用2.7所以简单做了一下精简。
只用了totp的模式。所以别的模式也还啊没验证。
敬请见谅。
不过很容易根据自己的需要修改。
注释请见上边的那个url。大部分是一致的。
'''
import base64
import random
import time
import hmac
import hashlib
import struct
MODE_TOTP = 'totp'
MODE_HOTP = 'hotp'
_modes = (MODE_TOTP, MODE_HOTP)
_TOTP_PRECISION = 30
_SECRET_LENGTH = 16
_CODE_LENGTH = 6
def _truncate(hmac_sha1, digits = _CODE_LENGTH):
offset = int(hmac_sha1[-1], 16)
binary = int(hmac_sha1[(offset * 2):((offset * 2) + 8)], 16) & 0x7fffffff
return str(binary)[-digits:]
def _code(secret, c, digits=_CODE_LENGTH):
secret_bytes = base64.b32decode(secret)
c_bytes = struct.pack('>Q', c)
hmac_sha1 = hmac.new(key=secret_bytes, msg=c_bytes,
digestmod=hashlib.sha1).hexdigest()
return _truncate(hmac_sha1, digits)
def auth(mode, secret, code, var = None, tolerance = 2):
if mode == MODE_HOTP:
c = 1 if var == None else var
tolerance_from = c
tolerance_to = c + tolerance
elif mode == MODE_TOTP:
ts = int(time.time()) if var == None else var
ticks = int(ts / _TOTP_PRECISION)
tolerance_from = ticks - tolerance
tolerance_to = ticks + tolerance
else:
raise ValueError('Unsupported mode')
for c in range(tolerance_from, (tolerance_to + 1)):
if code == _code(secret, c):
return True
return False
if __name__ == '__main__':
secret = 'xxxxxxxxxxxxx'
code = raw_input()
result = auth(MODE_TOTP,secret,code)
if result:
print 'ok'
else:
print 'fail'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment