Metadata-Version: 2.4
Name: mincrypt
Version: 1.1.8
Summary: Simple classical cryptography utilities.
Author: jishino
Author-email: jishino@gmail.com
License: MIT
Keywords: crypto,cryptography
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Terminals
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: keywords
Dynamic: license
Dynamic: requires-python
Dynamic: summary

`mincrypt` includes Caesar, Vigenere, XOR, and Rail Fence helpers, plus generic `encrypt()` and `decrypt()` functions for selecting an algorithm by name.

## Features

- Caesar shift encryption and decryption
- Vigenere encryption and decryption with repeating alphabetic keys
- XOR encryption that returns URL-safe Base64 tokens
- Rail Fence transposition encryption and decryption
- Generic algorithm dispatch with `encrypt()` and `decrypt()`
- Small helper functions for shifts, bytes, XOR, modulo, and rail patterns
- Custom exceptions for invalid keys and unknown algorithms

## Requirements

- Python 3.8 or newer

## Installation

From the project root, install the package in editable mode:

```bash
python -m pip install -e .
```

Or, during local development, keep the package directory on your `PYTHONPATH` and import it directly:

```python
import mincrypt
```

## Quick start

```python
from mincrypt import caesar, decrypt, encrypt, rail_fence, vigenere, xor

message = "Hello"

caesar_cipher = caesar.encrypt(message, shift=4)
print(caesar_cipher)
print(caesar.decrypt(caesar_cipher, shift=4))

vigenere_cipher = vigenere.encrypt(message, key="secret")
print(vigenere_cipher)
print(vigenere.decrypt(vigenere_cipher, key="secret"))

xor_cipher = xor.encrypt(message, key="secret")
print(xor_cipher)
print(xor.decrypt(xor_cipher, key="secret"))

rail_cipher = rail_fence.encrypt(message, rails=3)
print(rail_cipher)
print(rail_fence.decrypt(rail_cipher, rails=3))

# Generic helper
cipher = encrypt(message, algorithm="caesar", shift=2)
print(cipher)
print(decrypt(cipher, algorithm="caesar", shift=2))
```

Example output:

```text
Lipps
Hello
Zincs
Hello
OwAPHgo=
Hello
Hoell
Hello
Jgnnq
Hello
```

## Algorithms

### Caesar

Shift alphabetic characters by a fixed number. Uppercase and lowercase letters are preserved, and non-alphabetic characters are left unchanged.

```python
from mincrypt import caesar

cipher = caesar.encrypt("Attack at dawn!", shift=3)
plain = caesar.decrypt(cipher, shift=3)
```

### Vigenere

Encrypt text using a repeating alphabetic key. Non-alphabetic characters are preserved and do not consume key characters.

```python
from mincrypt import vigenere

cipher = vigenere.encrypt("Attack at dawn!", key="lemon")
plain = vigenere.decrypt(cipher, key="lemon")
```

A Vigenere key must contain at least one alphabetic character.

### XOR

XOR text with a repeating key. `encrypt()` returns a URL-safe Base64 token, and `decrypt()` converts that token back to text.

```python
from mincrypt import xor

cipher = xor.encrypt("Attack at dawn!", key="secret")
plain = xor.decrypt(cipher, key="secret")
```

For raw bytes, use `xor.xor_bytes()`:

```python
from mincrypt import xor

raw = xor.xor_bytes(b"data", b"key")
```

### Rail Fence

Encrypt text with a Rail Fence transposition using two or more rails.

```python
from mincrypt import rail_fence

cipher = rail_fence.encrypt("Attack at dawn!", rails=3)
plain = rail_fence.decrypt(cipher, rails=3)
```

## Generic API

Use `encrypt()` and `decrypt()` when you want to choose an algorithm dynamically:

```python
from mincrypt import encrypt, decrypt

cipher = encrypt("Hello", algorithm="caesar", shift=3)
plain = decrypt(cipher, algorithm="caesar", shift=3)
```

Supported algorithm names:

- `caesar`
- `vigenere`
- `xor`
- `rail_fence`
- `rail-fence`
- `railfence`

Algorithm-specific options are passed as keyword arguments:

```python
encrypt("Hello", algorithm="caesar", shift=3)
encrypt("Hello", algorithm="vigenere", key="secret")
encrypt("Hello", algorithm="xor", key="secret")
encrypt("Hello", algorithm="rail_fence", rails=3)
```

## Exceptions

```python
from mincrypt import InvalidAlgorithmError, InvalidKeyError
```

- `InvalidKeyError` is raised when a required key is empty or invalid.
- `InvalidAlgorithmError` is raised when the generic API receives an unknown algorithm name.

Example:

```python
from mincrypt import InvalidAlgorithmError, encrypt

try:
    encrypt("Hello", algorithm="unknown")
except InvalidAlgorithmError as exc:
    print(exc)
```

## Helper functions

The `fastcalc` module contains lower-level helpers used by the algorithms:

- `mod(value, base)`
- `shift_char(char, shift)`
- `shift_text(text, shift)`
- `alpha_shift_value(char)`
- `alpha_shift_values(text)`
- `text_to_bytes(value, encoding="utf-8")`
- `bytes_to_text(value, encoding="utf-8")`
- `repeat_key_bytes(key, length)`
- `xor_bytes(data, key)`
- `rail_index_pattern(length, rails)`
- `split_by_indexes(text, indexes, target)`

Most users should prefer the higher-level algorithm modules unless they need these building blocks directly.

## Project layout

```text
mincrypt/
├── __init__.py
├── caesar.py
├── exceptions.py
├── fastcalc.py
├── rail_fence.py
├── vigenere.py
└── xor.py
README.md
```
