diff --git a/totp.py b/totp.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a94d57afb1d2cc2a24b33c93782263d7bf8ef54
--- /dev/null
+++ b/totp.py
@@ -0,0 +1,31 @@
+import struct
+from sha1 import hmac_sha1
+from base32 import base32_decode
+
+
+
+def totp(time, key, step_secs=30, digits=6):
+    """
+    Time-based One-Time Password (TOTP) implementation based on https://tools.ietf.org/id/draft-mraihi-totp-timebased-06.html
+
+    >>> totp(1602659430, "DWRGVKRPQJLNU4GY", step_secs=30, digits=6)
+    ('846307', 30)
+    >>> totp(1602659435, "DWRGVKRPQJLNU4GY", step_secs=30, digits=6)
+    ('846307', 25)
+    >>> totp(1602659430, "DWRGVKRPQJLNU4GY", step_secs=30, digits=4)
+    ('6307', 30)
+    >>> totp(1602659430, "DWRGVKRPQJLNU4GY", step_secs=15, digits=6)
+    ('524508', 15)
+    """
+
+    hmac = hmac_sha1(base32_decode(key), struct.pack(">Q", time // step_secs))
+    offset = hmac[-1] & 0xF
+    code = ((hmac[offset] & 0x7F) << 24 |
+            (hmac[offset + 1] & 0xFF) << 16 |
+            (hmac[offset + 2] & 0xFF) << 8 |
+            (hmac[offset + 3] & 0xFF))
+    code = str(code % 10 ** digits)
+    return (
+        "0" * (digits - len(code)) + code,
+        step_secs - time % step_secs
+    )