Skip to content

Instantly share code, notes, and snippets.

@MayankFawkes
Created August 11, 2020 12:55
Show Gist options
  • Select an option

  • Save MayankFawkes/38c9874f7e31fab326e8e7cd20f0a40f to your computer and use it in GitHub Desktop.

Select an option

Save MayankFawkes/38c9874f7e31fab326e8e7cd20f0a40f to your computer and use it in GitHub Desktop.
Time-based One-time Password algorithm in python python3
import datetime
import time
import hashlib
import hmac
import base64
class OTP(object):
digits=6
digest=hashlib.sha1
def __init__(self,s: str) -> None:
self.secret = s
@staticmethod
def int_to_bytestring(i: int, padding: int = 8) -> bytes:
result = bytearray()
while i != 0:
result.append(i & 0xFF)
i >>= 8
return bytes(bytearray(reversed(result)).rjust(padding, b'\0'))
def byte_secret(self) -> bytes:
missing_padding = len(self.secret) % 8
if missing_padding != 0:
self.secret += '=' * (8 - missing_padding)
return base64.b32decode(self.secret, casefold=True)
def generate_otp(self, input: int) -> str:
hasher = hmac.new(self.byte_secret(), self.int_to_bytestring(input), self.digest)
hmac_hash = bytearray(hasher.digest())
offset = hmac_hash[-1] & 0xf
code = ((hmac_hash[offset] & 0x7f) << 24 |
(hmac_hash[offset + 1] & 0xff) << 16 |
(hmac_hash[offset + 2] & 0xff) << 8 |
(hmac_hash[offset + 3] & 0xff))
str_code = str(code % 10 ** self.digits)
while len(str_code) < self.digits:
str_code = '0' + str_code
return str_code[0:3]+"-"+str_code[3:6]
def Now(self) -> str:
return self.generate_otp(int(time.time()/30))
if __name__ == "__main__":
print(OTP("KEY HERE").Now())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment