Metadata-Version: 2.4
Name: cktotp
Version: 1.0.0
Summary: Simple TOTP implementation.
Author: Christopher Keefer
Author-email: Christopher Keefer <keefer@sanemethod.com>
License-File: LICENSE
Requires-Python: >=3.11
Project-URL: Documentation, https://github.com/ck-al/cktotp
Project-URL: Homepage, https://github.com/ck-al/cktotp
Project-URL: Repository, https://github.com/ck-al/cktotp.git
Description-Content-Type: text/markdown

# cktotp

`cktotp` is a small, dependency-free Python implementation of time-based one-time passwords (TOTP). It generates and verifies codes using a shared secret, HMAC digest, and configurable time window.

Requires Python 3.11 or newer.

## Installation
```shell
pip install cktotp
```
## Usage

Create a `TOTP` instance with a shared secret. The secret must be provided as `bytes`.
```python
from cktotp import TOTP

totp = TOTP(
    secret=b"shared-secret",
    digest="sha1",
    digits=6,
)

code = totp.at()
print(code)
```
By default, codes use SHA-1, contain six digits, and change every 30 seconds.

## Verify a code
```python
if totp.verify("123456"):
    print("Code is valid")
else:
    print("Code is invalid")
```
Verification uses the current time by default. To allow for clock drift, provide a window containing adjacent time intervals:
```python
is_valid = totp.verify("123456", window=1)
```
A window of `1` checks the previous, current, and next time intervals.

## Generate a code at a specific time

`at()` accepts a Unix timestamp, a `datetime`, or `None` to use the current time.
```python
from datetime import datetime, timezone

when = datetime.now(timezone.utc)
code = totp.at(when)

print(code)
```
## Check code expiration
```python
seconds_remaining = totp.expires()
print(f"Code expires in {seconds_remaining} seconds")
```
## Generate codes for a time range
```python
codes = totp.range(window=1)

for code in codes:
    print(code)
```
## Configuration

The main options are:

- `secret`: Shared secret as `bytes`.
- `digest`: Hash algorithm supported by Python's `hmac` module, such as `"sha1"`, `"sha256"`, or `"sha512"`.
- `digits`: Number of digits in a truncated code.
- `time_step`: Duration of each code interval in seconds. Defaults to `30`.
- `time_start`: Unix timestamp used as the start of the TOTP counter. Defaults to `0`.
- `truncate`: When `True`, return numeric OTP digits. When `False`, return the full HMAC digest as hexadecimal.
- `window`: Number of intervals before and after the current interval to accept during verification.

To return the full hexadecimal digest instead of a numeric code:
```python
digest = totp.at(truncate=False)
print(digest)
```
Alternatively, setting `digits` to `0` at init will cause all totps generated by that instance to return their full hexadecimal digest.

Keep shared secrets protected and use the same secret, digest, digit count, time step, and start time when generating and verifying codes.
