Skip to main content

Indic UID

PyPI version Python Versions License: MIT

Generate short, unique identifiers using characters from Indian language scripts (Devanagari, Gujarati, Kannada, Tamil, Telugu, Bengali) and English.

Perfect for referral codes, short URLs, or any system requiring unique identifiers with an Indian language touch!

✨ Features

  • 🎯 Multiple Scripts: Support for 7 Indian scripts (Devanagari, Gujarati, Kannada, Tamil, Telugu, Bengali, English)
  • 🔐 Cryptographically Secure: Uses Python's secrets module for secure random generation
  • 🎲 Flexible Generation: Choose between pure random or pronounceable IDs
  • 🔢 Numeric Support: Generate IDs with script-native numbers, or digits-only OTPs
  • ✅ Validation Built-in: Validate IDs and detect their script
  • 📊 Collision Analysis: Calculate probability of ID collisions
  • 🚀 Zero Dependencies: Lightweight, no external dependencies
  • 🎨 Simple API: Easy to use, intuitive interface

📦 Installation

pip install indic-uid

Note

The package is installed as indic-uid, but imported in Python as indic_uid

🚀 Quick Start

from indic_uid import generate_id

# Generate a random 6-character ID
id = generate_id()
print(id)  # Example: 'कஆಗઘతঅ'

# Generate with specific length
id = generate_id(length=8)
print(id)  # Example: 'अкஆগઘతaక'

# Generate from specific script
id = generate_id(scripts=['devanagari'])
print(id)  # Example: 'घअकआइश'

# Generate pronounceable IDs (alternates vowels and consonants)
id = generate_id(pronounceable=True, scripts=['devanagari'])
print(id)  # Example: 'कअखइगउ'

# Generate a numeric OTP in Devanagari
otp = generate_id(length=6, scripts=['devanagari'], numbers_only=True)
print(otp)  # Example: '३७५२१९'

📖 Usage Examples

Basic ID Generation

from indic_uid import generate_id, generate_batch

# Default: 6 characters, all scripts
id = generate_id()

# Custom length
short_id = generate_id(length=4)
long_id = generate_id(length=10)

# Generate multiple IDs at once
ids = generate_batch(count=10, length=5)
for id in ids:
    print(id)

Script Selection

# Single script
devanagari_id = generate_id(scripts=['devanagari'])
tamil_id = generate_id(scripts=['tamil'])

# Multiple scripts
mixed_id = generate_id(scripts=['devanagari', 'tamil', 'gujarati'])

# Available scripts
from indic_uid import get_available_scripts
print(get_available_scripts())
# Output: ['devanagari', 'gujarati', 'kannada', 'tamil', 'telugu', 'bengali', 'english']

Pronounceable IDs

Generate IDs that alternate between consonants and vowels for easier pronunciation:

# Pronounceable ID (easier to speak)
id = generate_id(pronounceable=True, scripts=['devanagari'])
print(id)  # Example: 'कअखइगउ' (ka-khi-gu)

# Works with any script
id = generate_id(pronounceable=True, scripts=['tamil'])
print(id)  # Example: 'கஅசஇடஉ'

Numeric IDs & OTPs

Generate IDs that include or consist entirely of script-native number characters:

# Include numbers in the character pool
id = generate_id(length=8, scripts=['devanagari'], include_numbers=True)
print(id)  # Example: 'क३ठ७अ२गइ' (mix of letters and digits)

# Generate digits-only OTPs
otp = generate_id(length=6, scripts=['devanagari'], numbers_only=True)
print(otp)  # Example: '३७५२१९'

# Tamil numeric OTP
otp = generate_id(length=4, scripts=['tamil'], numbers_only=True)
print(otp)  # Example: '௩௭௫௨'

# Multi-script numeric OTP
otp = generate_id(length=6, scripts=['devanagari', 'bengali'], numbers_only=True)
print(otp)  # Example: '३৭५২১९'

# Batch generate OTPs
otps = generate_batch(count=10, length=6, scripts=['devanagari'], numbers_only=True)

Validation

from indic_uid import is_valid_id, get_script_of_char

# Validate an ID
id = generate_id()
print(is_valid_id(id))  # True
print(is_valid_id('abc123'))  # False

# Validate with specific script
id = generate_id(scripts=['kannada'])
print(is_valid_id(id, scripts=['kannada']))  # True
print(is_valid_id(id, scripts=['tamil']))    # False

# Validate length
print(is_valid_id(id, length=6))  # True if ID is 6 chars

# Detect script of a character
char = 'क'
print(get_script_of_char(char))  # 'devanagari'

Collision Probability Analysis

from indic_uid import calculate_collision_probability, estimate_safe_id_count

# Calculate collision probability for your use case
prob = calculate_collision_probability(
    num_ids=10000,      # Expected number of IDs
    length=6,           # ID length
    num_scripts=6       # Number of scripts used
)
print(f"Collision probability: {prob:.2e}")
# Output: Collision probability: 5.45e-10 (extremely low!)

# Estimate safe number of IDs
safe_count = estimate_safe_id_count(
    length=6,
    num_scripts=6,
    max_collision_prob=0.000001  # 1 in a million
)
print(f"Safe ID count: {safe_count:,}")
# Output: Safe ID count: 13,856,406

🎯 Use Cases

Referral System

from indic_uid import generate_id

def create_referral_code(user_id):
    """Generate a unique referral code for a user."""
    referral_code = generate_id(length=6, scripts=['devanagari'])
    # Store mapping: referral_code -> user_id in database
    return referral_code

# Usage
code = create_referral_code(user_id=12345)
print(f"Your referral code: {code}")
# Share: https://yourapp.com/ref/{code}

Short URLs

from indic_uid import generate_id

def create_short_url(long_url):
    """Create a short URL identifier."""
    short_id = generate_id(length=5, scripts=['devanagari', 'gujarati'])
    # Store mapping: short_id -> long_url
    return f"https://short.link/{short_id}"

url = create_short_url("https://example.com/very/long/url/path")
print(url)  # https://short.link/कખગઘચ

Coupon Codes

from indic_uid import generate_id

def create_coupon_code(campaign_name):
    """Generate pronounceable coupon codes."""
    code = generate_id(
        length=6,
        pronounceable=True,
        scripts=['devanagari']
    )
    return code.upper()  # Note: Indian scripts don't have uppercase

coupon = create_coupon_code("diwali_sale")
print(f"Coupon: {coupon}")

📊 Collision Probability

With default settings (6 characters, all 7 scripts):

Number of IDs Collision Probability Odds
1,000 5.45 × 10⁻¹² 1 in 183 billion
10,000 5.45 × 10⁻¹⁰ 1 in 1.8 billion
100,000 5.45 × 10⁻⁸ 1 in 18 million
1,000,000 5.45 × 10⁻⁶ 1 in 183,000

Conclusion: Extremely safe for most applications. Even with 1 million IDs, collision probability is less than 0.0005%.

🌐 Supported Scripts

Script Example Characters Letters Numbers
Devanagari (Hindi) अ, क, ख, ग, घ 41 ०१२३४५६७८९
Gujarati અ, ક, ખ, ગ, ઘ 41 ૦૧૨૩૪૫૬૭૮૯
Kannada ಅ, ಕ, ಖ, ಗ, ಘ 44 ೦೧೨೩೪೫೬೭೮೯
Tamil அ, க, ங, ச, ஞ 30 ௦௧௨௩௪௫௬௭௮௯
Telugu అ, క, ఖ, గ, ఘ 44 ౦౧౨౩౪౫౬౭౮౯
Bengali অ, ক, খ, গ, ঘ 40 ০১২৩৪৫৬৭৮৯
English a, b, c, d, e 26 0123456789

Total character pool: ~240 letters + 70 number characters across all scripts

🔧 API Reference

generate_id(length=6, scripts=None, pronounceable=False, include_numbers=False, numbers_only=False)

Generate a unique ID.

Parameters:

  • length (int): Length of the ID (default: 6)
  • scripts (list): List of script names to use (default: all scripts)
  • pronounceable (bool): Alternate vowels/consonants (default: False)
  • include_numbers (bool): Include script-native digits in the character pool (default: False)
  • numbers_only (bool): Use only script-native digits — ideal for OTPs (default: False)

Returns: String containing the generated ID

Example:

id = generate_id(length=8, scripts=['devanagari', 'tamil'])
otp = generate_id(length=6, scripts=['devanagari'], numbers_only=True)

generate_batch(count, length=6, scripts=None, pronounceable=False, include_numbers=False, numbers_only=False)

Generate multiple IDs at once.

Parameters:

  • count (int): Number of IDs to generate
  • length (int): Length of each ID
  • scripts (list): List of script names
  • pronounceable (bool): Alternate vowels/consonants
  • include_numbers (bool): Include script-native digits
  • numbers_only (bool): Use only script-native digits

Returns: List of generated IDs

Example:

ids = generate_batch(100, length=5)
otps = generate_batch(10, length=6, scripts=['tamil'], numbers_only=True)

is_valid_id(id_string, scripts=None, length=None, include_numbers=False)

Validate if a string is a valid Indic ID.

Parameters:

  • id_string (str): The ID to validate
  • scripts (list): Expected scripts (default: any)
  • length (int): Expected length (default: any)
  • include_numbers (bool): Consider script-native numbers as valid (default: False)

Returns: Boolean

Example:

is_valid = is_valid_id('कखگઘచঅ', scripts=['devanagari'])

get_script_of_char(char)

Identify which script a character belongs to.

Parameters:

  • char (str): A single character

Returns: Script name (str) or None

Example:

script = get_script_of_char('क')  # Returns 'devanagari'

get_available_scripts()

Get list of all available scripts.

Returns: List of script names

Example:

scripts = get_available_scripts()
# ['devanagari', 'gujarati', 'kannada', 'tamil', 'telugu', 'bengali']

calculate_collision_probability(num_ids, length=6, num_scripts=6)

Calculate collision probability for given parameters.

Parameters:

  • num_ids (int): Expected number of IDs
  • length (int): ID length
  • num_scripts (int): Number of scripts being used

Returns: Float between 0 and 1


estimate_safe_id_count(length=6, num_scripts=6, max_collision_prob=0.000001)

Estimate safe number of IDs for given collision probability.

Parameters:

  • length (int): ID length
  • num_scripts (int): Number of scripts
  • max_collision_prob (float): Maximum acceptable collision probability

Returns: Integer (estimated safe count)

🤝 Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (pytest)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Development Setup

# Clone the repo
git clone https://github.com/aayush-mor13/indic-uid.git
cd indic-uid

# Install in development mode
pip install -e .

# Install dev dependencies
pip install pytest pytest-cov

# Run tests
pytest

# Run tests with coverage
pytest --cov=indic_uid

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

👥 Authors

🙏 Acknowledgments

  • Inspired by the beauty and diversity of Indian scripts
  • Built for the Indian developer community
  • Thanks to all contributors!

📫 Support

📈 Changelog

v0.1.0 (2025-01-22)

  • Initial release
  • Support for 6 Indian scripts + English
  • Random and pronounceable ID generation
  • Validation and script detection
  • Collision probability analysis

v0.2.0 (2026-03-24)

  • Added numeric ID support with script-native numbers
  • New feature: Digits-only OTP generation

Made with ❤️ for the Indian developer community

Metadata

Release files for indic-uid 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for indic-uid 0.2.0
File Size Uploaded Provenance Actions
indic_uid-0.2.0.tar.gz 17.0 kB Without provenance Details for indic_uid-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for indic-uid 0.2.0
File Interpreter ABI Platform Actions
indic_uid-0.2.0-py3-none-any.whl Python 3 none any Details for indic_uid-0.2.0-py3-none-any.whl

Total release size: 29.1 kB

Release files / indic_uid-0.2.0.tar.gz

Download URL indic_uid-0.2.0.tar.gz
Size 17.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f9736f2ec942103b4d34863234c3a682f161bdf681d686c4ed7fee462b7ae0f5
BLAKE2b-256 checksum
How to use checksums
0c28863a6192e9bcf02cb8ad2b90610817b23f5e610e194353062b098b3753af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / indic_uid-0.2.0-py3-none-any.whl

Download URL indic_uid-0.2.0-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0dcf0737ce3904e7d2a306db2c4bf2b92e03b4606ab4b7b9ede5728c92cde468
BLAKE2b-256 checksum
How to use checksums
f01fab63d43e1e8e9b8253b2cbfb5c323a357b5a3f8184a5acbacf99624cb425
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for indic-uid 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page