# cuuid - Compact UUID Library

[![Python Version](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Python 3.12+ library for efficient UUID generation, serialization, and encoding with compact representation.

## Features

- **Compact Serialization**: Reduces UUID storage from 16 bytes to 2-17 bytes (up to 87% space savings)
- **Multiple UUID Versions**: Supports UUID v1, v3, v4, and v5
- **Data UUIDs**: Embed up to 15 bytes of arbitrary data (`str` or `bytes`) inside a UUID
- **Custom Encoding**: Base59 encoding for human-readable representations
- **Type Safe**: Comprehensive type hints for static analysis
- **Zero Dependencies**: No external dependencies required

## Requirements

- Python 3.12 or higher

## Installation

```bash
pip install cuuid
```

Or install from source:

```bash
git clone https://github.com/dubalu/cuuid.git
cd cuuid
pip install .
```

## Quick Start

```python
from cuuid import uuid1, uuid4, uuid5, NAMESPACE_DNS

# Generate UUID v4 (random)
u4 = uuid4()
print(u4)  # e.g., '73e94ff7-45db-4f9f-bd20-e751e221baa3'

# Generate UUID v1 (timestamp-based)
u1 = uuid1()
print(u1)  # e.g., '16fdd0ac-f98c-11f0-a5c5-34363b644ed4'

# Generate UUID v5 (SHA-1 hash)
u5 = uuid5(NAMESPACE_DNS, 'example.com')
print(u5)  # 'cfbff0d1-9375-5685-968c-48ce8b15ae17'

# Compact serialization
serialized = u4.serialise()
print(f"Size: {len(serialized)} bytes")  # Much smaller than 16 bytes!

# Encoding
encoded = u4.encode()
print(encoded)  # Base59 encoded representation
```

## API Reference

### UUID Generation

```python
from cuuid import uuid, uuid1, uuid3, uuid4, uuid5, NAMESPACE_DNS

# Create new UUID with optional compaction
u = uuid()  # Creates UUID v1 with auto-compaction

# UUID v1: Timestamp and MAC address
u1 = uuid1(node=None, clock_seq=None)

# UUID v3: MD5 hash of namespace and name
u3 = uuid3(NAMESPACE_DNS, "example.com")

# UUID v4: Random UUID
u4 = uuid4()

# UUID v5: SHA-1 hash of namespace and name
u5 = uuid5(NAMESPACE_DNS, "example.com")
```

### Serialization

```python
from cuuid import UUID, encode, decode, unserialise

# Serialize UUID to compact bytes
u = uuid4()
serialized = u.serialise()

# Deserialize bytes back to UUID
uuid_list = unserialise(serialized)

# Encode to different formats
encoded_default = encode(serialized)  # Default encoding
encoded_guid = encode(serialized, 'guid')  # GUID format
encoded_urn = encode(serialized, 'urn')  # URN format

# Decode back to bytes
decoded = decode(encoded_default)
```

### Data UUIDs

Store up to 15 bytes of arbitrary data inside a UUID:

```python
from cuuid import UUID

# From a string (encoded as UTF-8)
u = UUID(data='hello')
print(u.data())  # b'hello'

# From raw bytes
u = UUID(data=b'\x01\x02\x03')
print(u.data())  # b'\x01\x02\x03'
```

### Compact UUIDs

```python
from cuuid import uuid1

# Generate UUID v1
u = uuid1()

# Check if UUID can be compacted
compacted = u.compact_crush()
if compacted:
    print(f"Original: {u}")
    print(f"Compacted: {compacted}")
    print(f"Is compact: {compacted.iscompact()}")
```

## Migration from Python 2.7

**Version 1.0.0** is a complete rewrite for Python 3.12+. If you're upgrading from the Python 2.7 version:

### Breaking Changes

- **Python 2.7 no longer supported** - Minimum version is now Python 3.12
- **Removed `six` dependency** - All compatibility shims removed
- **Type hints added** - All public and private APIs now have type annotations

### API Compatibility

The public API remains **100% compatible**. All existing code using the following functions will continue to work:

- `UUID`, `uuid()`, `uuid1()`, `uuid3()`, `uuid4()`, `uuid5()`
- `encode()`, `decode()`, `encode_uuid()`, `decode_uuid()`
- `unserialise()`
- Namespace constants: `NAMESPACE_DNS`, `NAMESPACE_URL`, `NAMESPACE_OID`, `NAMESPACE_X500`

### What Changed Internally

1. **Removed Python 2 compatibility layer** (`six` library)
2. **Fixed integer division** for Python 3 semantics
3. **Modernized bytes/string handling** for Python 3
4. **Added comprehensive type hints** (PEP 695)
5. **F-strings** for all string formatting (PEP 701)
6. **Modern packaging** with `pyproject.toml`

## Technical Details

### Compact Serialization Format

The library uses a variable-length encoding scheme:

- **Full format**: 17 bytes (1 byte marker + 16 bytes UUID)
- **Condensed format**: 4-16 bytes (optimized based on UUID content)
- **Compacted format**: 2-13 bytes (for timestamp-based UUIDs with predictable node)

### UUID Layout

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           time_low                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           time_mid            |       time_hi_and_version     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|clk_seq_hi_res |  clk_seq_low  |          node (0-1)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         node (2-5)                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

time = 60 bits
clock = 14 bits
node = 48 bits
```

## Development

### Type Checking

The library includes comprehensive type hints. Use mypy for static type checking:

```bash
mypy src/cuuid/ --strict
```

### Linting

Use ruff for linting:

```bash
ruff check src/cuuid/
```

### Testing

Install dev dependencies and run the test suite:

```bash
pip install -e ".[dev]"
pytest
```

## License

MIT License - Copyright (c) 2026 Dubalu International LLC

See [LICENSE](LICENSE) file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Links

- **Repository**: https://github.com/dubalu/cuuid
- **Issues**: https://github.com/dubalu/cuuid/issues
- **Documentation**: https://github.com/dubalu/cuuid/wiki

## Changelog

### Version 1.1.1

#### Added
- `UUID(data=...)` now accepts `bytes` in addition to `str`

### Version 1.0.0 (2026-01-24)

**Major Release - Python 3.12+ Only**

#### Breaking Changes
- Dropped Python 2.7 support
- Minimum Python version is now 3.12
- Removed `six` compatibility library

#### Added
- Comprehensive type hints (PEP 695)
- Modern packaging with `pyproject.toml`
- F-string formatting (PEP 701)
- Type marker file (`py.typed`)

#### Changed
- Migrated from `_random` to public `random` module
- Fixed integer division for Python 3 semantics
- Improved bytes/string handling
- Modernized code style and documentation

#### Fixed
- Exception handling (removed deprecated `.message` attribute)
- Character encoding/decoding for Python 3
- BaseX encoding algorithm integer division

---

Made with ❤️ by Dubalu International LLC
