Skip to content

Instantly share code, notes, and snippets.

@GoWind
Created January 28, 2017 08:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GoWind/97cc76e3aa20b4c40e7c1c7bb74568ad to your computer and use it in GitHub Desktop.
Save GoWind/97cc76e3aa20b4c40e7c1c7bb74568ad to your computer and use it in GitHub Desktop.
TOTP implementation
import hashlib
import time
import math
import hmac
def lpad(x, padlen=16):
if len(x) >= padlen:
return x
return '0'*(padlen-len(x)) + x
class TOTP:
def __init__(self, key, digest_type, digits, step):
self.key = bytearray.fromhex(key)
self.digest_type = digest_type
self.digits = digits
self.step = step
def create_token(self):
cur_time = int(math.floor(time.time()))
steps = cur_time / self.step
steps_hex = lpad(hex(steps)[2:])
steps_bytes = bytearray.fromhex(steps_hex)
hasho = hmac.new(self.key, steps_bytes, digestmod=self.digest_type).hexdigest()
hash_bytes = bytearray.fromhex(hasho)
offset = hash_bytes[len(hash_bytes)-1] & 0xf
number = hash_bytes[offset:offset+4]
token = ((number[0] & 0x7f) << 24) | ((number[1] & 0xff) << 16) | ((number[2] & 0xff) << 8) | (number[3] & 0xff)
return token % (10**self.digits)
## Test implementation
t = TOTP('3132333435363738393031323334353637383930', hashlib.sha1, 8, 30)
print t.create_token()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment