# -*- coding: utf-8 -*-

import hmac
import base64
import struct
import hashlib
import time
import math


def get_hotp_token(key, intervals_no):
    msg = struct.pack(">Q", intervals_no)
    h = hmac.new(key, msg, hashlib.sha1).digest()
    o = ord(h[19]) & 15
    h = (struct.unpack(">I", h[o:o + 4])[0] & 0x7fffffff) % 1000000
    return h


def get_totp_token(key):
    token = get_hotp_token(key, intervals_no=int(time.time()) // 30)
    return str(token).zfill(6)


def get_totp_time_remaining():
    return int(30 - (time.time() % 30))


def is_otp_secret_valid(secret):
    try:
        secret = secret.replace(' ', '')
        if not len(secret):
            return False
        secret = secret.ljust(int(math.ceil(len(secret) / 16.0) * 16), '=')
        key = base64.b32decode(secret, casefold=True)
        get_totp_token(key)
    except:
        return False

    return True


def get_hotp_key(key=None, secret=None, hexkey=None):
    if hexkey:
        key = hexkey.decode('hex')
    if secret:
        secret = secret.replace(' ', '')
        secret = secret.ljust(int(math.ceil(len(secret) / 16.0) * 16), '=')
        key = base64.b32decode(secret, casefold=True)
    return key

@@ -89,20 +89,8 @@
 ime%0A
-import math%0A
 %0A%0Ade
@@ -521,24 +521,280 @@
 () %25 30))%0A%0A%0A
+def pad_base32_str(str, padding_char):%0A    str_len = len(str)%0A    missing_padding = str_len %25 8%0A    if missing_padding != 0:%0A        # str += '=' * (8 - missing_padding)%0A        str = str.ljust(str_len + 8 - missing_padding, padding_char)%0A    return str%0A%0A%0A
 def is_otp_s
@@ -938,60 +938,29 @@
 t = 
-secret.ljust(int(math.ceil(len(secret) / 16.0) * 16)
+pad_base32_str(secret
 , '=
@@ -1277,60 +1277,29 @@
 t = 
-secret.ljust(int(math.ceil(len(secret) / 16.0) * 16)
+pad_base32_str(secret
 , '=

Fix base32 padding error