Skip to content

Instantly share code, notes, and snippets.

@smitelli
Created August 2, 2018 22:54
Show Gist options
  • Save smitelli/56d00685114e22845f3d63527127c321 to your computer and use it in GitHub Desktop.
Save smitelli/56d00685114e22845f3d63527127c321 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import base64
import getpass
import hmac
import struct
import time
def make_hotp(secret_bytes, counter, length):
counter_bytes = struct.pack('>Q', counter)
hotp_bytes = hmac.new(
secret_bytes, msg=counter_bytes, digestmod='sha1').digest()
offset = hotp_bytes[-1] & 0xF
hotp = (struct.unpack(
'>I', hotp_bytes[offset:offset + 4]
)[0] & 0x7FFFFFFF) % (10 ** length)
return str(hotp).zfill(length)
def make_totp(secret_bytes, interval, length):
counter, rem = divmod(int(time.time()), interval)
ttl = interval - rem
return make_hotp(secret_bytes, counter, length), ttl
def main():
secret = getpass.getpass('TOTP secret seed: ')
interval = input('Interval (seconds, default 30): ') or 30
length = input('Output length (default 6): ') or 6
print()
print('Generating codes below. Press Ctrl+C to stop.')
secret_bytes = base64.b32decode(secret, casefold=True)
endl = (' ' * len(str(interval))) + '\r'
while True:
try:
totp, ttl = make_totp(secret_bytes, int(interval), int(length))
print(' {0} ({1})'.format(totp, ttl), end=endl)
time.sleep(1)
except KeyboardInterrupt:
print()
break
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment