Skip to content

Instantly share code, notes, and snippets.

@vimiomori
Last active October 25, 2023 03:26
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vimiomori/e1c32e5ac1682bc02fb56da8ab8fbdc4 to your computer and use it in GitHub Desktop.
Save vimiomori/e1c32e5ac1682bc02fb56da8ab8fbdc4 to your computer and use it in GitHub Desktop.
# https://medium.com/@vivian.muchen/implementing-your-own-time-based-otp-generator-3b971a31330b
import hmac
import base64
counter = 0
secret = base64.b32encode(b"password")
def low_order_4_bits(val):
return val & 0b1111
def last_31_bits(p):
res = bytearray()
res.append(p[0] & 0x7F) # 7 bits
for b in p[1:]:
res.append(b & 0xFF) # 8 bits
return res
def DT(hs):
offset = low_order_4_bits(hs[19])
p = hs[offset:offset+4]
return last_31_bits(p)
def hotp(k, c):
counter_bytes = c.to_bytes(8, byteorder='big') # 8-byte, big-edian
hs_hmac = hmac.new(k, counter_bytes, "sha1")
hs = hs_hmac.digest()
s_bits = DT(hs)
s_num = int(s_bits.hex(), 16)
return s_num % 10 ** 6
import datetime
import time
t = 30
def totp(k, t):
s_since_epoch = time.mktime(datetime.datetime.now().timetuple())
time_steps = int(s_since_epoch / t)
return hotp(k, time_steps)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment