Gestalt Illusion Captcha Generator for Python
Project description
Dotcha 🌀
Dotcha is a high-performance Python library for generating captchas based on the Gestalt Illusion principle. It creates visual patterns from thousands of geometric shapes that are intuitive for humans but highly resistant to automated OCR and AI solvers.
Features
- 🎨 Gestalt Illusion: Pure geometric rendering for maximum machine-learning resistance.
- ⚡ High Performance: Optimized rendering (~30ms per PNG).
- 🔄 Animated GIFs: "Temporal Gestalt" effect where text is reconstruction through motion.
- 🛡️ Fuzzy Validation: Intelligent answer verification with Levenshtein distance.
- 🌓 Universal Themes: Light, Dark, and fully customizable color schemas.
- 📉 Scalable Difficulty: Dynamic calibration from clear patterns to chaotic noise.
- 🤖 Async Ready: Native
asynciosupport for web frameworks and bots.
Visual Examples
| Light Theme (EASY) | Dark Theme (MEDIUM) | Animated (Temporal Gestalt) |
|---|---|---|
Installation
pip install Pillow
Quick Start
Synchronous PNG
from dotcha import CaptchaGenerator, Theme
gen = CaptchaGenerator(theme=Theme.LIGHT)
text, buffer = gen.generate()
with open("captcha.png", "wb") as f:
f.write(buffer.read())
print(f"Generated captcha: {text}")
Asynchronous GIF
from dotcha import CaptchaGenerator, Theme, Difficulty
async def send_captcha():
gen = CaptchaGenerator(theme=Theme.DARK, difficulty=Difficulty.HARD)
text, buffer = await gen.agenerate_gif(frames=12)
💡 See examples/bot_demo.py for a complete Telegram bot integration.
Fuzzy Verification
from dotcha import CaptchaGenerator
user_input = "ABCDE"
actual = "ABCD1"
# Accepts answer with 1 char distance
is_valid, distance = CaptchaGenerator.check_answer(user_input, actual, fuzzy_tolerance=1)
if is_valid:
print(f"Passed! Distance: {distance}")
Why Dotcha?
- Pattern-Based Security: While a human brain naturally connects scattered dots into characters, standard OCR algorithms perceive them as disconnected noise.
- Temporal Signal: The GIF format utilizes "Temporal Sparsity". A static frame is unreadable, but the human eye integrates movement into a clear signal.
- Zero Disk Footprint: Captchas are generated directly into byte buffers, making it ideal for high-concurrency environments.
- Stable & Lightweight: Explicit resource management and minimal dependencies.
Performance
Static Images (PNG)
| Difficulty | Time | Shapes | Description |
|---|---|---|---|
| EASY | ~0.05s | 8000 | High density, very clear for humans. |
| MEDIUM | ~0.03s | 5000 | Balanced density and noise. |
| HARD | ~0.02s | 3500 | Sparse text, higher background chaos. |
Animated Captchas (GIF)
| Difficulty | Time (12 frames) | Security Level |
|---|---|---|
| EASY | ~0.51s | Maximum (High signal integration) |
| MEDIUM | ~0.38s | Standard |
| HARD | ~0.32s | Extreme (Sparse signal in motion) |
Note: Timings are based on a standard modern CPU. Generation is offloaded to background threads to keep your bot responsive.
License
This project is released into the public domain under the Unlicense.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dotcha-0.1.0.tar.gz.
File metadata
- Download URL: dotcha-0.1.0.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4fb513ab300d4d72db2769624f1f096462a03a50f292dad6a4e6b31ba9530098
|
|
| MD5 |
1e395c381479f3259cfd48094e9bf43b
|
|
| BLAKE2b-256 |
5b9160cb1a2ce0a63b24539d07986f848916275c78c9853a61b89b2bc1cb2e10
|
Provenance
The following attestation bundles were made for dotcha-0.1.0.tar.gz:
Publisher:
publish.yml on trombalny/dotcha
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotcha-0.1.0.tar.gz -
Subject digest:
4fb513ab300d4d72db2769624f1f096462a03a50f292dad6a4e6b31ba9530098 - Sigstore transparency entry: 1097119224
- Sigstore integration time:
-
Permalink:
trombalny/dotcha@cd9df9544c68afddb0805c0942ef43a00f70829b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/trombalny
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cd9df9544c68afddb0805c0942ef43a00f70829b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file dotcha-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dotcha-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9cfa6683ce4ef9dc1f8a8e695c6bed02e0de41373951f9cf793f4bd3208e401
|
|
| MD5 |
5d42621c4055b2eb5d59f745848d62e5
|
|
| BLAKE2b-256 |
0547890f58bbdff287447d9f01c981399b17daf599383def4fe9dfbd271f483f
|
Provenance
The following attestation bundles were made for dotcha-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on trombalny/dotcha
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotcha-0.1.0-py3-none-any.whl -
Subject digest:
b9cfa6683ce4ef9dc1f8a8e695c6bed02e0de41373951f9cf793f4bd3208e401 - Sigstore transparency entry: 1097119284
- Sigstore integration time:
-
Permalink:
trombalny/dotcha@cd9df9544c68afddb0805c0942ef43a00f70829b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/trombalny
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cd9df9544c68afddb0805c0942ef43a00f70829b -
Trigger Event:
workflow_dispatch
-
Statement type: