Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/artesoscuras_dicma.py.json
T

1 line
135 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "artesoscuras/dicma.py", "files": {"README.md": {"1a90281838c305e2716dc27c81ad4d5536080e94": {"t": 1785674036.3122544, "n": 6801, "h": "8c7c4690453da660", "c": "# DICMA — The Dictionary Maker\n\nDicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any word or concept. Users often create passwords based on specific words and modify them with symbols, numbers, and capitalization — Dicma generates all those combinations.\n\n---\n\n## Setup\n\n```bash\npip install openai\n```\n\nOn first run, Dicma creates `config.txt` with LLM provider examples. The default is **Ollama** (local, no API key required):\n\n```bash\npython3 dicma.py\n# → config.txt is created automatically\n```\n\n### Ollama (default, local, free)\n\n```bash\n# Install and start Ollama\nbrew install ollama # macOS\n# or: curl -fsSL https://ollama.com/install.sh | sh # Linux\nollama serve\n\n# Pull the default model\nollama pull llama3.2:3b\n\n# Done — config.txt is already set for Ollama\n```\n\n### DeepSeek (recommended for best results)\n\n1. Sign up at https://platform.deepseek.com\n2. Copy your API key\n3. Edit `config.txt` and uncomment the DeepSeek section:\n\n```ini\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.deepseek.com\"\nMODEL = \"deepseek-v4-flash\"\n```\n\n### Other providers\n\n```ini\n# === OpenAI ===\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.openai.com/v1\"\nMODEL = \"gpt-4o-mini\"\n```\n\n---\n\n## Modes\n\n### USERS mode (`-u`)\n\nGenerates username combinations from names and surnames using common IT department patterns.\n\n```\n# Two words (name + surname)\npython3 dicma.py -u \"jony random\"\n# → jony.random, jrandom, jony_random, random.jony, j.r, jr, jony, ...\n\n# Three words (name + two surnames)\npython3 dicma.py -u \"jony random smith\"\n# → jony.random.smith, jrs, j.r.s, jony.randoms, j_random_smith, ...\n\n# Light mode: only the most common IT patterns (~10 patterns)\npython3 dicma.py -u \"jony random\" -l\n# → jony.random, jrandom, jony_random, j.random, jony.r, ...\n\n# From file\npython3 dicma.py -u users.txt -o usernames.txt\n```\n\n---\n\n### PASSWORD mode (`-p`)\n\nGenerates password variations with suffixes, prefixes, leet speak, numbers and symbols.\n\n```\n# Basic (no LLM): password-patterns only\npython3 dicma.py -p \"dragon\"\n# → dragon, Dragon, DRAGON, dr@gon, dragon1, dragon123, ...\n\n# Save to file\npython3 dicma.py -p \"dragon\" -o dic.txt\n\n# Light mode (~7K lines per word)\npython3 dicma.py -p \"dragon\" -l -o dic.txt\n\n# Full mode (~5M lines per word)\npython3 dicma.py -p \"dragon\" -f -o dic.txt\n\n# From file with a custom dictionary for pattern extraction\npython3 dicma.py -p words.txt -d rockyou.txt -o dic.txt\n```\n\n**With LLM expansion** (`-n1`). Finds semantically related words first, then passworizes them:\n\n```\n# Expand \"dragon\" with 20 semantic neighbours, then passworize all\npython3 dicma.py -p \"dragon\" -n1 20 -o dic.txt\n\n# Multi-level expansion\npython3 dicma.py -p \"starwars\" -n1 20 -n2 10 -n3 5 -o dic.txt\n```\n\n`-n1` triggers LLM mode. `-n2` and `-n3` add indirect neighbours (second and third degree). Each level multiplies the number of base words before password patterns are applied, resulting in larger dictionaries.\n\n---\n\n### JUST-NEIGHBOURS mode (`-jn`)\n\nFind semantically related words using an LLM. No password patterns applied — just plain words.\n\n```\n# Basic: 20 related words for \"starwars\"\npython3 dicma.py -jn \"starwars\" -n1 20\n# → jedi, skywalker, lightsaber, darthvader, sith, ...\n\n# Two levels: 20 direct + 10 indirect per direct result\npython3 dicma.py -jn \"starwars\" -n1 20 -n2 10\n\n# Three levels\npython3 dicma.py -jn \"dragon\" -n1 20 -n2 10 -n3 5\n\n# Save to file\npython3 dicma.py -jn \"starwars\" -n1 20 -o neighbours.txt\n\n# Multiple input words\npython3 dicma.py -jn \"starwars,finalfantasy\" -n1 20\n```\n\n---\n\n### RULES mode (`-r`)\n\nGenerates a **Hashcat rule file** that applies the same case, leet, suffix, and prefix transformations directly to a wordlist — without generating massive dictionaries on disk.\n\n```\n# Default (~2.25M rules, 80 MB)\npython3 dicma.py -r -o dicma.rules\n\n# Light mode (~5K rules, 0.2 MB)\npython3 dicma.py -r -l -o light.rules\n\n# Full mode (~55M rules, 1.3 GB — for desktop GPUs with 8+ GB VRAM)\npython3 dicma.py -r -f -o full.rules\n\n# With custom dictionary for pattern extraction\npython3 dicma.py -r -d rockyou.txt -o custom.rules\n```\n\n**Each rule combines case + leet + suffix/prefix in a single line.** This matches the same transformations that `-p` mode produces, but applied on-the-fly by Hashcat's GPU engine:\n\n```\n$1$2$3 → append \"123\"\nc sa@ ss$ ^8^0 $9$4 → capitalize + a→@ + s→$ + prepend \"08\" + append \"94\"\nl so0 ^*^* $1$1$5 → lowercase + o→0 + prepend \"**\" + append \"115\"\nu sa@ so0 se3 ss$ □3□3 □1□5□9 → uppercase + 4 leet subs + prepend \"33\" + append \"159\"\n```\n\n**Usage with Hashcat:**\n\n```bash\n# Generate rules\npython3 dicma.py -r -o dicma.rules\n\n# Crack with a wordlist\nhashcat -a 0 -m 0 hash.txt wordlist.txt -r dicma.rules\n```\n\n**Rule count vs dictionary size (per word):**\n\n| Mode | Rules | File size | Equivalent dicma `-p` |\n|---|---|---|---|\n| `-r -l` | 5K | 0.2 MB | ~7.7K lines/word |\n| `-r` | 2.25M | 80 MB | ~278K lines/word |\n| `-r -f` | 55M | 1.3 GB | ~5M lines/word |\n\n**Pattern coverage (`-r` default):**\n\n| Pattern | Used | Available |\n|---|---|---|\n| Suffixes (simple) | 800 (74%) | 1,080 |\n| Prefixes (simple) | 50 (7%) | 659 |\n| Numeric | 200 (38%) | 515 |\n| Symbols | 50 (50%) | 100 |\n| Combo pref×suf | 63×350 | 659×1,080 |\n\nFull mode (`-r -f`) covers 100% of all patterns. Requires a GPU with enough VRAM (e.g., RTX 3070 with 8 GB or cloud GPU).\n\n---\n\n## Full help\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD | -jn JUST_NEIGHBOURS)\n [-l] [-f] [-nv] [-d file_name] [-o file_name]\n [-n1 N1] [-n2 N2] [-n3 N3]\n [--api-key API_KEY] [--base-url BASE_URL]\n [--model MODEL] [--config CONFIG]\n```\n\n| Flag | Description |\n|---|---|\n| `-u` | Users mode: generate username combinations |\n| `-p` | Password mode: generate password variations |\n| `-jn` | Just neighbours: find related words (LLM) |\n| `-r` | Rules mode: generate Hashcat rules |\n| `-l` | Light mode (users: IT patterns only, passwords/rules: fewer outputs) |\n| `-f` | Full mode (passwords: ~5M lines/word, rules: 55M rules) |\n| `-nv` | No verbose: only output the dictionary |\n| `-d` | Custom dictionary for pattern extraction |\n| `-o` | Output file (otherwise prints to stdout) |\n| `-n1` | Level-1 neighbours per input word (triggers LLM) |\n| `-n2` | Level-2 neighbours per level-1 result (LLM) |\n| `-n3` | Level-3 neighbours per level-2 result (LLM) |\n| `--api-key` | LLM API key (or env var LLM_API_KEY) |\n| `--base-url` | LLM API base URL (default from config.txt) |\n| `--model` | LLM model name (default from config.txt) |\n| `--config` | Config file path (default: config.txt) |\n\nConfig precedence: CLI args > env vars > config.txt > defaults.\n"}, "037e305e788fdb03c47901a814df59b3b66f66ec": {"t": 1785763922.4862764, "n": 6801, "h": "8c7c4690453da660", "c": "# DICMA — The Dictionary Maker\n\nDicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any word or concept. Users often create passwords based on specific words and modify them with symbols, numbers, and capitalization — Dicma generates all those combinations.\n\n---\n\n## Setup\n\n```bash\npip install openai\n```\n\nOn first run, Dicma creates `config.txt` with LLM provider examples. The default is **Ollama** (local, no API key required):\n\n```bash\npython3 dicma.py\n# → config.txt is created automatically\n```\n\n### Ollama (default, local, free)\n\n```bash\n# Install and start Ollama\nbrew install ollama # macOS\n# or: curl -fsSL https://ollama.com/install.sh | sh # Linux\nollama serve\n\n# Pull the default model\nollama pull llama3.2:3b\n\n# Done — config.txt is already set for Ollama\n```\n\n### DeepSeek (recommended for best results)\n\n1. Sign up at https://platform.deepseek.com\n2. Copy your API key\n3. Edit `config.txt` and uncomment the DeepSeek section:\n\n```ini\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.deepseek.com\"\nMODEL = \"deepseek-v4-flash\"\n```\n\n### Other providers\n\n```ini\n# === OpenAI ===\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.openai.com/v1\"\nMODEL = \"gpt-4o-mini\"\n```\n\n---\n\n## Modes\n\n### USERS mode (`-u`)\n\nGenerates username combinations from names and surnames using common IT department patterns.\n\n```\n# Two words (name + surname)\npython3 dicma.py -u \"jony random\"\n# → jony.random, jrandom, jony_random, random.jony, j.r, jr, jony, ...\n\n# Three words (name + two surnames)\npython3 dicma.py -u \"jony random smith\"\n# → jony.random.smith, jrs, j.r.s, jony.randoms, j_random_smith, ...\n\n# Light mode: only the most common IT patterns (~10 patterns)\npython3 dicma.py -u \"jony random\" -l\n# → jony.random, jrandom, jony_random, j.random, jony.r, ...\n\n# From file\npython3 dicma.py -u users.txt -o usernames.txt\n```\n\n---\n\n### PASSWORD mode (`-p`)\n\nGenerates password variations with suffixes, prefixes, leet speak, numbers and symbols.\n\n```\n# Basic (no LLM): password-patterns only\npython3 dicma.py -p \"dragon\"\n# → dragon, Dragon, DRAGON, dr@gon, dragon1, dragon123, ...\n\n# Save to file\npython3 dicma.py -p \"dragon\" -o dic.txt\n\n# Light mode (~7K lines per word)\npython3 dicma.py -p \"dragon\" -l -o dic.txt\n\n# Full mode (~5M lines per word)\npython3 dicma.py -p \"dragon\" -f -o dic.txt\n\n# From file with a custom dictionary for pattern extraction\npython3 dicma.py -p words.txt -d rockyou.txt -o dic.txt\n```\n\n**With LLM expansion** (`-n1`). Finds semantically related words first, then passworizes them:\n\n```\n# Expand \"dragon\" with 20 semantic neighbours, then passworize all\npython3 dicma.py -p \"dragon\" -n1 20 -o dic.txt\n\n# Multi-level expansion\npython3 dicma.py -p \"starwars\" -n1 20 -n2 10 -n3 5 -o dic.txt\n```\n\n`-n1` triggers LLM mode. `-n2` and `-n3` add indirect neighbours (second and third degree). Each level multiplies the number of base words before password patterns are applied, resulting in larger dictionaries.\n\n---\n\n### JUST-NEIGHBOURS mode (`-jn`)\n\nFind semantically related words using an LLM. No password patterns applied — just plain words.\n\n```\n# Basic: 20 related words for \"starwars\"\npython3 dicma.py -jn \"starwars\" -n1 20\n# → jedi, skywalker, lightsaber, darthvader, sith, ...\n\n# Two levels: 20 direct + 10 indirect per direct result\npython3 dicma.py -jn \"starwars\" -n1 20 -n2 10\n\n# Three levels\npython3 dicma.py -jn \"dragon\" -n1 20 -n2 10 -n3 5\n\n# Save to file\npython3 dicma.py -jn \"starwars\" -n1 20 -o neighbours.txt\n\n# Multiple input words\npython3 dicma.py -jn \"starwars,finalfantasy\" -n1 20\n```\n\n---\n\n### RULES mode (`-r`)\n\nGenerates a **Hashcat rule file** that applies the same case, leet, suffix, and prefix transformations directly to a wordlist — without generating massive dictionaries on disk.\n\n```\n# Default (~2.25M rules, 80 MB)\npython3 dicma.py -r -o dicma.rules\n\n# Light mode (~5K rules, 0.2 MB)\npython3 dicma.py -r -l -o light.rules\n\n# Full mode (~55M rules, 1.3 GB — for desktop GPUs with 8+ GB VRAM)\npython3 dicma.py -r -f -o full.rules\n\n# With custom dictionary for pattern extraction\npython3 dicma.py -r -d rockyou.txt -o custom.rules\n```\n\n**Each rule combines case + leet + suffix/prefix in a single line.** This matches the same transformations that `-p` mode produces, but applied on-the-fly by Hashcat's GPU engine:\n\n```\n$1$2$3 → append \"123\"\nc sa@ ss$ ^8^0 $9$4 → capitalize + a→@ + s→$ + prepend \"08\" + append \"94\"\nl so0 ^*^* $1$1$5 → lowercase + o→0 + prepend \"**\" + append \"115\"\nu sa@ so0 se3 ss$ □3□3 □1□5□9 → uppercase + 4 leet subs + prepend \"33\" + append \"159\"\n```\n\n**Usage with Hashcat:**\n\n```bash\n# Generate rules\npython3 dicma.py -r -o dicma.rules\n\n# Crack with a wordlist\nhashcat -a 0 -m 0 hash.txt wordlist.txt -r dicma.rules\n```\n\n**Rule count vs dictionary size (per word):**\n\n| Mode | Rules | File size | Equivalent dicma `-p` |\n|---|---|---|---|\n| `-r -l` | 5K | 0.2 MB | ~7.7K lines/word |\n| `-r` | 2.25M | 80 MB | ~278K lines/word |\n| `-r -f` | 55M | 1.3 GB | ~5M lines/word |\n\n**Pattern coverage (`-r` default):**\n\n| Pattern | Used | Available |\n|---|---|---|\n| Suffixes (simple) | 800 (74%) | 1,080 |\n| Prefixes (simple) | 50 (7%) | 659 |\n| Numeric | 200 (38%) | 515 |\n| Symbols | 50 (50%) | 100 |\n| Combo pref×suf | 63×350 | 659×1,080 |\n\nFull mode (`-r -f`) covers 100% of all patterns. Requires a GPU with enough VRAM (e.g., RTX 3070 with 8 GB or cloud GPU).\n\n---\n\n## Full help\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD | -jn JUST_NEIGHBOURS)\n [-l] [-f] [-nv] [-d file_name] [-o file_name]\n [-n1 N1] [-n2 N2] [-n3 N3]\n [--api-key API_KEY] [--base-url BASE_URL]\n [--model MODEL] [--config CONFIG]\n```\n\n| Flag | Description |\n|---|---|\n| `-u` | Users mode: generate username combinations |\n| `-p` | Password mode: generate password variations |\n| `-jn` | Just neighbours: find related words (LLM) |\n| `-r` | Rules mode: generate Hashcat rules |\n| `-l` | Light mode (users: IT patterns only, passwords/rules: fewer outputs) |\n| `-f` | Full mode (passwords: ~5M lines/word, rules: 55M rules) |\n| `-nv` | No verbose: only output the dictionary |\n| `-d` | Custom dictionary for pattern extraction |\n| `-o` | Output file (otherwise prints to stdout) |\n| `-n1` | Level-1 neighbours per input word (triggers LLM) |\n| `-n2` | Level-2 neighbours per level-1 result (LLM) |\n| `-n3` | Level-3 neighbours per level-2 result (LLM) |\n| `--api-key` | LLM API key (or env var LLM_API_KEY) |\n| `--base-url` | LLM API base URL (default from config.txt) |\n| `--model` | LLM model name (default from config.txt) |\n| `--config` | Config file path (default: config.txt) |\n\nConfig precedence: CLI args > env vars > config.txt > defaults.\n"}, "dc3046fac06f18cfc9eadc4f85c1ab919efdf552": {"t": 1785763923.727195, "n": 5229, "h": "1f025c818ce1df7b", "c": "# DICMA V2 — The Dictionary Maker\n\nDicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any word or concept. Users often create passwords based on specific words and modify them with symbols, numbers, and capitalization — Dicma generates all those combinations.\n\nDicma V2 removes deprecated Fasttext machine learning model and use LLM models to generate words related. You can use it with local llm (using ollama for example), or you can use your llm suscription to any platform api compatible with openai library. My personal recomendation is deepseek-v4-flash from https://www.deepseek.com/en/.\n\n---\n\n## Setup\n\n```bash\npip install openai\n```\n\nOn first run, Dicma creates `config.txt` with LLM provider examples. The default is **Ollama** (local, no API key required):\n\n```bash\npython3 dicma.py\n# → config.txt is created automatically\n```\n\n### Ollama (default, local, free)\n\n```bash\n# Install and start Ollama\nbrew install ollama # macOS\n# or: curl -fsSL https://ollama.com/install.sh | sh # Linux\nollama serve\n\n# Pull the default model\nollama pull llama3.2:3b\n\n# Done — config.txt is already set for Ollama\n```\n\n### DeepSeek (recommended for best results)\n\n1. Sign up at https://platform.deepseek.com\n2. Copy your API key\n3. Edit `config.txt` and uncomment the DeepSeek section:\n\n```ini\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.deepseek.com\"\nMODEL = \"deepseek-v4-flash\"\n```\n\n### Other providers\n\n```ini\n# === OpenAI ===\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.openai.com/v1\"\nMODEL = \"gpt-4o-mini\"\n```\n\n---\n\n## Modes\n\n### USERS mode (`-u`)\n\nGenerates username combinations from names and surnames using common IT department patterns.\n\n```\n# Two words (name + surname)\npython3 dicma.py -u \"jony random\"\n# → jony.random, jrandom, jony_random, random.jony, j.r, jr, jony, ...\n\n# Three words (name + two surnames)\npython3 dicma.py -u \"jony random smith\"\n# → jony.random.smith, jrs, j.r.s, jony.randoms, j_random_smith, ...\n\n# Light mode: only the most common IT patterns (~10 patterns)\npython3 dicma.py -u \"jony random\" -l\n# → jony.random, jrandom, jony_random, j.random, jony.r, ...\n\n# From file\npython3 dicma.py -u users.txt -o usernames.txt\n```\n\n---\n\n### PASSWORD mode (`-p`)\n\nGenerates password variations with suffixes, prefixes, leet speak, numbers and symbols.\n\n```\n# Basic (no LLM): password-patterns only\npython3 dicma.py -p \"dragon\"\n# → dragon, Dragon, DRAGON, dr@gon, dragon1, dragon123, ...\n\n# Save to file\npython3 dicma.py -p \"dragon\" -o dic.txt\n\n# Light mode (~7K lines per word)\npython3 dicma.py -p \"dragon\" -l -o dic.txt\n\n# Full mode (~5M lines per word)\npython3 dicma.py -p \"dragon\" -f -o dic.txt\n\n# From file with a custom dictionary for pattern extraction\npython3 dicma.py -p words.txt -d rockyou.txt -o dic.txt\n```\n\n**With LLM expansion** (`-n1`). Finds semantically related words first, then passworizes them:\n\n```\n# Expand \"dragon\" with 20 semantic neighbours, then passworize all\npython3 dicma.py -p \"dragon\" -n1 20 -o dic.txt\n\n# Multi-level expansion\npython3 dicma.py -p \"starwars\" -n1 20 -n2 10 -n3 5 -o dic.txt\n```\n\n`-n1` triggers LLM mode. `-n2` and `-n3` add indirect neighbours (second and third degree). Each level multiplies the number of base words before password patterns are applied, resulting in larger dictionaries.\n\n---\n\n### JUST-NEIGHBOURS mode (`-jn`)\n\nFind semantically related words using an LLM. No password patterns applied — just plain words.\n\n```\n# Basic: 20 related words for \"starwars\"\npython3 dicma.py -jn \"starwars\" -n1 20\n# → jedi, skywalker, lightsaber, darthvader, sith, ...\n\n# Two levels: 20 direct + 10 indirect per direct result\npython3 dicma.py -jn \"starwars\" -n1 20 -n2 10\n\n# Three levels\npython3 dicma.py -jn \"dragon\" -n1 20 -n2 10 -n3 5\n\n# Save to file\npython3 dicma.py -jn \"starwars\" -n1 20 -o neighbours.txt\n\n# Multiple input words\npython3 dicma.py -jn \"starwars,finalfantasy\" -n1 20\n```\n\n---\n\n## Full help\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD | -jn JUST_NEIGHBOURS)\n [-l] [-f] [-nv] [-d file_name] [-o file_name]\n [-n1 N1] [-n2 N2] [-n3 N3]\n [--api-key API_KEY] [--base-url BASE_URL]\n [--model MODEL] [--config CONFIG]\n```\n\n| Flag | Description |\n|---|---|\n| `-u` | Users mode: generate username combinations |\n| `-p` | Password mode: generate password variations |\n| `-jn` | Just neighbours: find related words (LLM) |\n| `-l` | Light mode (users: IT patterns only, passwords: ~7K lines/word) |\n| `-f` | Full mode (passwords: ~5M lines/word) |\n| `-nv` | No verbose: only output the dictionary |\n| `-d` | Custom dictionary for pattern extraction |\n| `-o` | Output file (otherwise prints to stdout) |\n| `-n1` | Level-1 neighbours per input word (triggers LLM) |\n| `-n2` | Level-2 neighbours per level-1 result (LLM) |\n| `-n3` | Level-3 neighbours per level-2 result (LLM) |\n| `--api-key` | LLM API key (or env var LLM_API_KEY) |\n| `--base-url` | LLM API base URL (default from config.txt) |\n| `--model` | LLM model name (default from config.txt) |\n| `--config` | Config file path (default: config.txt) |\n\nConfig precedence: CLI args > env vars > config.txt > defaults.\n"}, "11c5217b5ca817b7b744ce80aa5fd63d3d6b57bc": {"t": 1785763925.0469294, "n": 4891, "h": "879ddf532d4bd27f", "c": "# DICMA — The Dictionary Maker\n\nDicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any word or concept. Users often create passwords based on specific words and modify them with symbols, numbers, and capitalization — Dicma generates all those combinations.\n\n---\n\n## Setup\n\n```bash\npip install openai\n```\n\nOn first run, Dicma creates `config.txt` with LLM provider examples. The default is **Ollama** (local, no API key required):\n\n```bash\npython3 dicma.py\n# → config.txt is created automatically\n```\n\n### Ollama (default, local, free)\n\n```bash\n# Install and start Ollama\nbrew install ollama # macOS\n# or: curl -fsSL https://ollama.com/install.sh | sh # Linux\nollama serve\n\n# Pull the default model\nollama pull llama3.2:3b\n\n# Done — config.txt is already set for Ollama\n```\n\n### DeepSeek (recommended for best results)\n\n1. Sign up at https://platform.deepseek.com\n2. Copy your API key\n3. Edit `config.txt` and uncomment the DeepSeek section:\n\n```ini\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.deepseek.com\"\nMODEL = \"deepseek-v4-flash\"\n```\n\n### Other providers\n\n```ini\n# === OpenAI ===\nAPI_KEY = \"sk-your_key\"\nBASE_URL = \"https://api.openai.com/v1\"\nMODEL = \"gpt-4o-mini\"\n```\n\n---\n\n## Modes\n\n### USERS mode (`-u`)\n\nGenerates username combinations from names and surnames using common IT department patterns.\n\n```\n# Two words (name + surname)\npython3 dicma.py -u \"jony random\"\n# → jony.random, jrandom, jony_random, random.jony, j.r, jr, jony, ...\n\n# Three words (name + two surnames)\npython3 dicma.py -u \"jony random smith\"\n# → jony.random.smith, jrs, j.r.s, jony.randoms, j_random_smith, ...\n\n# Light mode: only the most common IT patterns (~10 patterns)\npython3 dicma.py -u \"jony random\" -l\n# → jony.random, jrandom, jony_random, j.random, jony.r, ...\n\n# From file\npython3 dicma.py -u users.txt -o usernames.txt\n```\n\n---\n\n### PASSWORD mode (`-p`)\n\nGenerates password variations with suffixes, prefixes, leet speak, numbers and symbols.\n\n```\n# Basic (no LLM): password-patterns only\npython3 dicma.py -p \"dragon\"\n# → dragon, Dragon, DRAGON, dr@gon, dragon1, dragon123, ...\n\n# Save to file\npython3 dicma.py -p \"dragon\" -o dic.txt\n\n# Light mode (~7K lines per word)\npython3 dicma.py -p \"dragon\" -l -o dic.txt\n\n# Full mode (~5M lines per word)\npython3 dicma.py -p \"dragon\" -f -o dic.txt\n\n# From file with a custom dictionary for pattern extraction\npython3 dicma.py -p words.txt -d rockyou.txt -o dic.txt\n```\n\n**With LLM expansion** (`-n1`). Finds semantically related words first, then passworizes them:\n\n```\n# Expand \"dragon\" with 20 semantic neighbours, then passworize all\npython3 dicma.py -p \"dragon\" -n1 20 -o dic.txt\n\n# Multi-level expansion\npython3 dicma.py -p \"starwars\" -n1 20 -n2 10 -n3 5 -o dic.txt\n```\n\n`-n1` triggers LLM mode. `-n2` and `-n3` add indirect neighbours (second and third degree). Each level multiplies the number of base words before password patterns are applied, resulting in larger dictionaries.\n\n---\n\n### JUST-NEIGHBOURS mode (`-jn`)\n\nFind semantically related words using an LLM. No password patterns applied — just plain words.\n\n```\n# Basic: 20 related words for \"starwars\"\npython3 dicma.py -jn \"starwars\" -n1 20\n# → jedi, skywalker, lightsaber, darthvader, sith, ...\n\n# Two levels: 20 direct + 10 indirect per direct result\npython3 dicma.py -jn \"starwars\" -n1 20 -n2 10\n\n# Three levels\npython3 dicma.py -jn \"dragon\" -n1 20 -n2 10 -n3 5\n\n# Save to file\npython3 dicma.py -jn \"starwars\" -n1 20 -o neighbours.txt\n\n# Multiple input words\npython3 dicma.py -jn \"starwars,finalfantasy\" -n1 20\n```\n\n---\n\n## Full help\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD | -jn JUST_NEIGHBOURS)\n [-l] [-f] [-nv] [-d file_name] [-o file_name]\n [-n1 N1] [-n2 N2] [-n3 N3]\n [--api-key API_KEY] [--base-url BASE_URL]\n [--model MODEL] [--config CONFIG]\n```\n\n| Flag | Description |\n|---|---|\n| `-u` | Users mode: generate username combinations |\n| `-p` | Password mode: generate password variations |\n| `-jn` | Just neighbours: find related words (LLM) |\n| `-l` | Light mode (users: IT patterns only, passwords: ~7K lines/word) |\n| `-f` | Full mode (passwords: ~5M lines/word) |\n| `-nv` | No verbose: only output the dictionary |\n| `-d` | Custom dictionary for pattern extraction |\n| `-o` | Output file (otherwise prints to stdout) |\n| `-n1` | Level-1 neighbours per input word (triggers LLM) |\n| `-n2` | Level-2 neighbours per level-1 result (LLM) |\n| `-n3` | Level-3 neighbours per level-2 result (LLM) |\n| `--api-key` | LLM API key (or env var LLM_API_KEY) |\n| `--base-url` | LLM API base URL (default from config.txt) |\n| `--model` | LLM model name (default from config.txt) |\n| `--config` | Config file path (default: config.txt) |\n\nConfig precedence: CLI args > env vars > config.txt > defaults.\n"}, "3dbda3172ec99e60498674adba8d3debb13297e3": {"t": 1785763928.907756, "n": 5974, "h": "ca615cddba56d0b3", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name] [-ml file_name]\n [-n integer]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptions:\n -h, --help show this help message and exit\n -u, --users USERS File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d, --dictionary file_name\n Extract patterns from your an specific dictionary.\n -o, --output file_name\n Dictionary will be stored in this file.\n -ml, --machine-learning-model file_name\n Use a trained machine learning model to include neighbors of your original words.\n -n, --neighbours-number integer\n Ammount of neighbors for each word (20 by Default).\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\nOn actual version up to 3 word names are supported.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines x word). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines x word).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n\n<br>\n\n### MACHINE LEARNING mode:\n\n <mark>WARNING!! 11GB ram required for this option.</mark>\n\nOnly available for password mode. This mode will allow you to use a machine learning model to find the nearest possible words to the actual input words. For example, if you use \"queen\" as input, the nearest neighbors will be \"queens\", \"princess\", \"women\", etc... This will help you to find other words to passworize, but will increase your final dictionary a lot (Light mode recommended). As more details you know from the user, more keywords you will find when trying to map their mind. With this methode you can create realistic wordlists to crack the password of an specific user.\n\n<br>\n\nThe `-ml` flag will allow you to set the machine learning model. You can download this trained models from -> https://fasttext.cc/docs/en/crawl-vectors.html\n\n(You need to download the .bin file for the lenguage you want.)\n\n<br>\n\nThe `-n` flag will allow you to specify how many neighbors you want for any input word (20 by default).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l -ml cc.es.300.bin -n 100`\n\n<br>\n\nLINUX / MACOS USERS: For Linux and MacOS dicma will use \"fasttext\" python library. This can be installed like this:\n\n```\ngit clone https://github.com/facebookresearch/fastText.git\ncd fastText\nsudo pip install .\n```\nMore details can be found here -> https://fasttext.cc/docs/en/support.html\n\n<br>\n\nWINDOWS USERS: For Windows users \"fasttext\" python library have problems to be compiled so dicma will use the windows compiled binary \"fasttext.exe\". If the binary is not located in the same folder will prompt you to download fasttext.exe. This binary can be found at -> https://github.com/sigmeta/fastText-Windows\n\nTo make sure dicma can find fasttext.exe make sure that is in your current working directory.\n"}, "fb45714df465d607d146a69443acd37e7d6da810": {"t": 1785763931.275991, "n": 5923, "h": "77ee35c2e7ce4957", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name] [-ml file_name]\n [-n integer]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptions:\n -h, --help show this help message and exit\n -u, --users USERS File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d, --dictionary file_name\n Extract patterns from your an specific dictionary.\n -o, --output file_name\n Dictionary will be stored in this file.\n -ml, --machine-learning-model file_name\n Use a trained machine learning model to include neighbors of your original words.\n -n, --neighbours-number integer\n Ammount of neighbors for each word (20 by Default).\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines x word). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines x word).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n\n<br>\n\n### MACHINE LEARNING mode:\n\n <mark>WARNING!! 11GB ram required for this option.</mark>\n\nOnly available for password mode. This mode will allow you to use a machine learning model to find the nearest possible words to the actual input words. For example, if you use \"queen\" as input, the nearest neighbors will be \"queens\", \"princess\", \"women\", etc... This will help you to find other words to passworize, but will increase your final dictionary a lot (Light mode recommended). As more details you know from the user, more keywords you will find when trying to map their mind. With this methode you can create realistic wordlists to crack the password of an specific user.\n\n<br>\n\nThe `-ml` flag will allow you to set the machine learning model. You can download this trained models from -> https://fasttext.cc/docs/en/crawl-vectors.html\n\n(You need to download the .bin file for the lenguage you want.)\n\n<br>\n\nThe `-n` flag will allow you to specify how many neighbors you want for any input word (20 by default).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l -ml cc.es.300.bin -n 100`\n\n<br>\n\nLINUX / MACOS USERS: For Linux and MacOS dicma will use \"fasttext\" python library. This can be installed like this:\n\n```\ngit clone https://github.com/facebookresearch/fastText.git\ncd fastText\nsudo pip install .\n```\nMore details can be found here -> https://fasttext.cc/docs/en/support.html\n\n<br>\n\nWINDOWS USERS: For Windows users \"fasttext\" python library have problems to be compiled so dicma will use the windows compiled binary \"fasttext.exe\". If the binary is not located in the same folder will prompt you to download fasttext.exe. This binary can be found at -> https://github.com/sigmeta/fastText-Windows\n\nTo make sure dicma can find fasttext.exe make sure that is in your current working directory.\n"}, "e512ab6e0322782c799f1c0eb8b13b9ada9e7c04": {"t": 1785763932.5345604, "n": 5862, "h": "18f4fcf156e737e8", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name] [-ml file_name]\n [-n integer]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptions:\n -h, --help show this help message and exit\n -u, --users USERS File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d, --dictionary file_name\n Extract patterns from your an specific dictionary.\n -o, --output file_name\n Dictionary will be stored in this file.\n -ml, --machine-learning-model file_name\n Use a trained machine learning model to include neighbors of your original words.\n -n, --neighbours-number integer\n Ammount of neighbors for each word (20 by Default).\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines x word). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines x word).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n\n<br>\n\n### MACHINE LEARNING mode:\n\nOnly available for password mode. This mode will allow you to use a machine learning model to find the nearest possible words to the actual input words. For example, if you use \"queen\" as input, the nearest neighbors will be \"queens\", \"princess\", \"women\", etc... This will help you to find other words to passworize, but will increase your final dictionary a lot (Light mode recommended). As more details you know from the user, more keywords you will find when trying to map their mind. With this methode you can create realistic wordlists to crack the password of an specific user.\n\n<br>\n\nThe `-ml` flag will allow you to set the machine learning model. You can download this trained models from -> https://fasttext.cc/docs/en/crawl-vectors.html\n\n(You need to download the .bin file for the lenguage you want.)\n\n<br>\n\nThe `-n` flag will allow you to specify how many neighbors you want for any input word (20 by default).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l -ml cc.es.300.bin -n 100`\n\n<br>\n\nLINUX / MACOS USERS: For Linux and MacOS dicma will use \"fasttext\" python library. This can be installed like this:\n\n```\ngit clone https://github.com/facebookresearch/fastText.git\ncd fastText\nsudo pip install .\n```\nMore details can be found here -> https://fasttext.cc/docs/en/support.html\n\n<br>\n\nWINDOWS USERS: For Windows users \"fasttext\" python library have problems to be compiled so dicma will use the windows compiled binary \"fasttext.exe\". If the binary is not located in the same folder will prompt you to download fasttext.exe. This binary can be found at -> https://github.com/sigmeta/fastText-Windows\n\nTo make sure dicma can find fasttext.exe make sure that is in your current working directory.\n"}, "e5379c659d2158d420701e5caf350f3d36bc50e1": {"t": 1785763934.1446128, "n": 5884, "h": "20f0c8949e0d9aa9", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name] [-ml file_name]\n [-n integer]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptions:\n -h, --help show this help message and exit\n -u, --users USERS File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d, --dictionary file_name\n Extract patterns from your an specific dictionary.\n -o, --output file_name\n Dictionary will be stored in this file.\n -ml, --machine-learning-model file_name\n Use a trained machine learning model to include neighbors of your original words.\n -n, --neighbours-number integer\n Ammount of neighbors for each word (20 by Default).\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines x word). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines x word).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n\n<br>\n\n### MACHINE LEARNING mode:\n\nOnly available for password mode. This mode will allow you to use a machine learning model to find the nearest possible words to the actual input words. For example, if you use \"queen\" as input, the nearest neighbors will be \"queens\", \"princess\", \"women\", etc... This will help you to find other words to passworize, but will increase your final dictionary a lot (Light mode recommended). As more details you know from the user, more keywords you will find when trying to map their mind. With this methode you can create realistic wordlists to crack the password of an specific user.\n\n<br>\n\nThe `-ml` flag will allow you to set the machine learning model. You can download this trained models from -> https://fasttext.cc/docs/en/pretrained-vectors.html\n\n(You need to download the .bin file, the \"bin+text\", for the lenguage you want.)\n\n<br>\n\nThe `-n` flag will allow you to specify how many neighbors you want for any input word (20 by default).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l -ml cc.es.300.bin -n 100`\n\n<br>\n\nLINUX / MACOS USERS: For Linux and MacOS dicma will use \"fasttext\" python library. This can be installed like this:\n\n```\ngit clone https://github.com/facebookresearch/fastText.git\ncd fastText\nsudo pip install .\n```\nMore details can be found here -> https://fasttext.cc/docs/en/support.html\n\n<br>\n\nWINDOWS USERS: For Windows users \"fasttext\" python library have problems to be compiled so dicma will use the windows compiled binary \"fasttext.exe\". If the binary is not located in the same folder will prompt you to download fasttext.exe. This binary can be found at -> https://github.com/sigmeta/fastText-Windows\n\nTo make sure dicma can find fasttext.exe make sure that is in your current working directory.\n"}, "afef7b3c96ac73f70e9496a86c2f78a1a9317c3d": {"t": 1785763936.1651943, "n": 5868, "h": "3f0a911a3ddd6d4d", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name] [-ml file_name]\n [-n integer]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptions:\n -h, --help show this help message and exit\n -u, --users USERS File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d, --dictionary file_name\n Extract patterns from your an specific dictionary.\n -o, --output file_name\n Dictionary will be stored in this file.\n -ml, --machine-learning-model file_name\n Use a trained machine learning model to include neighbors of your original words.\n -n, --neighbours-number integer\n Ammount of neighbors for each word (20 by Default).\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines x word). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines x word).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n\n<br>\n\n### MACHINE LEARNING mode:\n\nOnly available for password mode. This mode will allow you to use a machine learning model to find the nearest possible words to the actual input words. For example, if you use \"queen\" as input, the nearest neighbors will be \"queens\", \"princess\", \"women\", etc... This will help you to find other words to passworize, but will increase your final dictionary a lot (Light mode recommended). As more details you know from the user, more keywords you will find when trying to map their mind. With this methode you can create realistic wordlists to crack the password of an specific user.\n\n<br>\n\nThe `-ml` flag will allow you to set the machine learning model. You can download this trained models from -> https://fasttext.cc/docs/en/pretrained-vectors.html\n\n(You need to download the .bin file, the \"bin+text\", for the lenguage you want.)\n\n<br>\n\nThe `-n` flag will allow you to specify how many neighbors you want for any input word.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l -ml cc.es.300.bin -n 100`\n\n<br>\n\nLINUX / MACOS USERS: For Linux and MacOS dicma will use \"fasttext\" python library. This can be installed like this:\n\n```\ngit clone https://github.com/facebookresearch/fastText.git\ncd fastText\nsudo pip install .\n```\nMore details can be found here -> https://fasttext.cc/docs/en/support.html\n\n<br>\n\nWINDOWS USERS: For Windows users \"fasttext\" python library have problems to be compiled so dicma will use the windows compiled binary \"fasttext.exe\". If the binary is not located in the same folder will prompt you to download fasttext.exe. This binary can be found at -> https://github.com/sigmeta/fastText-Windows\n\nTo make sure dicma can find fasttext.exe make sure that is in your current working directory.\n"}, "0d8a6262aabc1db45ca4a0880456a50ae73f4d8d": {"t": 1785763937.6061227, "n": 3869, "h": "684d7f2cac40859c", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptional arguments:\n -h, --help show this help message and exit\n -u USERS, --users USERS\n File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p PASSWORD, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d file_name, --dictionary file_name\n Extract patterns from your specific dictionary\n -o file_name, --output file_name\n Dictionary will be stored in this file.\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines x word). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines x word).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n"}, "31737df4f51b7125ec62760b18f60ded0cc32943": {"t": 1785763938.9267302, "n": 3855, "h": "17f4c979fc0d6473", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptional arguments:\n -h, --help show this help message and exit\n -u USERS, --users USERS\n File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p PASSWORD, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d file_name, --dictionary file_name\n Extract patterns from your specific dictionary\n -o file_name, --output file_name\n Dictionary will be stored in this file.\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n<br>\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\n<br>\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\n<br>\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\n<br>\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n"}, "e62fbdfd3ad75e3e67a27cbe3c5b6783c07b50d1": {"t": 1785763940.3037007, "n": 3825, "h": "636d55964c01fef2", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from the rockyou.txt dictionary to \"passworize\" any specific word or concept.\nUsers often create passwords based on specific words or concepts. They modify these with symbols, numbers, and capitalization to meet password requirements.\n\nUnfortunately, this behavior can be predictable, as some patterns are more commonly used than others. Dicma extracts these patterns from massive dictionaries, and you can even use your own custom dictionary to extract patterns. All possible combinations are returned for password cracking purposes using tools like Hashcat, John the Ripper, or others.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptional arguments:\n -h, --help show this help message and exit\n -u USERS, --users USERS\n File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p PASSWORD, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d file_name, --dictionary file_name\n Extract patterns from your specific dictionary\n -o file_name, --output file_name\n Dictionary will be stored in this file.\n```\n\n### USERS mode:\n\nThis mode allows you to input a list of usernames and surnames (e.g., from an Active Directory environment) and generates a list of possible combinations based on commonly used naming patterns in IT departments.\n\nInput can be a file (one name per line) or a string like \"john kenedy, albert random, patrick harper, ...\".\nThe output can be printed to the terminal or saved to a file using the `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of the tool and can generate a massive list of possible passwords based on specific words or concepts. You can provide these words via a text file (one per line) or a list like \"hotel, ibis, corporate, ...\".\nThe output can be shown in the terminal or (recommended) saved to a file with the `-o` flag.\n\nExample: The word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\nUse the `--dictionary` flag to specify a custom dictionary to extract patterns from.\nBy default, Dicma uses internal patterns extracted from the famous rockyou.txt dictionary.\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n\nThe `-l` flag enables LIGHT mode, which produces a shorter dictionary output (5,000–10,000 lines). \n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\nThe `-f` flag enables FULL mode, which generates a massive dictionary output (~5,000,000 lines).\n\n`python3 dicma.py -p words.txt -o dictionary.txt -l`\n\nThe `-nv` flag disables verbose output and only prints the dictionary. Errors will still be displayed.\n\n`python3 dicma.py -p words.txt -vn > dictionary.txt`\n\nMassive mode: this is triggered automatically when Dicma detects a large input. It will display progress information and estimated output size.\nIn massive mode, an output file is required. If you don’t specify one with the -o flag, Dicma will default to saving it in `./output.txt`.\n"}, "90f5336965f711a99cdea3531d9ac6d431f24921": {"t": 1785763944.0328808, "n": 3184, "h": "89b507dfccd4a8b5", "c": "# DICMA (The dictionary maker)\n\n### Dicma creates massive wordlists based on specific words for password cracking.\n\nIt includes extracted patterns from rockyou.txt dictionary to \"passworize\" any specific word or concept. \nCommontly users use a specific word or concept to create their passwords. They modify the concept with simbols, and also they attach numbers and simbols to acomplish the password requirements.\nUnfortunatly this behavior coult be predicteble because some of this patterns are used more than others. Dicma extract this patterns from masive dictionaryes and you can even use your specific dicitonary to extract the patterns. All possible combinations are returned for password cracking purpose, using hashcat, john the ripper, or any other software.\n\n```\nusage: dicma.py [-h] (-u USERS | -p PASSWORD) [-l] [-f] [-nv] [-d file_name] [-o file_name]\n\nWelcome to DICMA. The Dictionary Maker:\n\noptional arguments:\n -h, --help show this help message and exit\n -u USERS, --users USERS\n File with usernames, or usernames list: \"jony random,fahim jordan,...\"\n -p PASSWORD, --password PASSWORD\n file with words to \"passworize\", or list like: \"ibis,megacorp,...\"\n -l, --light Light mode, for small list (passwd mode).\n -f, --full Full mode. Warning, the output could be very heavy (passwd mode).\n -nv, --no-verbose Remove any output except the dictionary itself (Errors will be shown anyway).\n -d file_name, --dictionary file_name\n Extract patterns from your specific dictionary\n -o file_name, --output file_name\n Dictionary will be stored in this file.\n```\n\n### USERS mode:\n\nThis mode allows you to introduce a list of specific names and surnames from users that you expect to find in an Active directory enviroment and creates a list of all possible combinations based on the most used metods from IT departments.\nThe input can be a file, containing names and surnames (one per line) or an string like \"john kenedy, albert random, patrick harper, ...\". The output cand be printed on termianl or stored in a file with `-o` flag.\n\nExample: The user \"John Kenedy\" will be processed like:\n\n`python3 dicma.py -u \"john kenedy\"`\n\n`python3 dicma.py -u usernames.txt -o possible_users.txt`\n```\njohnkenedy\njohn.kenedy\nj_kenedy\njohn-k\n...\n```\n\n\n### PASSWORD mode:\n\nThis is the main mode of this tool, and can generate a massive list of possible password based on specific words or concetps. You can introduce this words from a text file (one per line) or a list like \"hotel, ibis, corporate, ...\". Output can be printed throug terminal or (more recomended) stored in a file with `-o` flag.\n\nExample: word \"hotel\" will be processed like:\n\n`python3 dicma.py -p \"hotel\"`\n\n`python3 dicma.py -p words.txt -o dictionary.txt`\n```\nhotel\nHotel\nHOTEL\nhotel1\n...\n!H0TEL2024\nh0tel123!\n...\n```\n\n`--dictionary` flag allows you to specify specific dicionary from wich you want to extract the patterns. By default, will use internaly stored patterns extracted from a famous dictionary (rockyou.txt)\n\n`python3 dicma.py -p words.txt -o dictionary.txt -d rockyou.txt`\n"}, "76f45e8517c213b08438470fa03081a68b74bbcf": {"t": 1785763947.0962803, "n": 642, "h": "50c07c659c17e258", "c": "# DICMA (The dictionary maker)\n\nDicma creates massive wordlists based on specific words for password cracking. Dicma includes extracted patterns from rockyou.txt dictionary to \"passworize\" any specific word or concept. \nCommontly users use a specific word or concept to create their passwords. They modify the concept with simbols, and also they attach numbers and simbols to acomplish the password requirements.\nUnfortunatly this behavior coult be predicteble because some of this patterns are used more than others. Dicma extract this patterns from masive dictionaryes and you can even use your specific dicitonary to extract the patterns.\n"}}, "dicma.py": {"1a90281838c305e2716dc27c81ad4d5536080e94": {"t": 1785674054.0075192, "n": 63235, "h": "1c28033240535377", "c": "#!/usr/bin/env python3\n\n# This project is from ArtesOscuras github repo.\n\n#-----------------------------------------------------\n# INTERNAL CONFIGURATION PARAMETERS FOR PASSWORD MODE:\n# -----------------------\n#\n# Light mode parameters:\namount_of_sufixs_used_light_mode = 200\namount_of_prefixs_used_light_mode = 50\n\n# Default mode parameters:\namount_of_sufixs_used = 1000\namount_of_prefixs_used = 200\n\n# Extended mode parameters:\namount_of_numericpat_used = 516\namount_of_symbolpat_used = 100\n#-----------------------------------------------------\n\n\n# Libraries to import\nimport sys\nimport os\nimport json\nimport argparse\nfrom itertools import product\nimport re\nfrom collections import Counter\nimport unicodedata\nimport subprocess\nimport multiprocessing\nimport platform\nimport ctypes\n\nfrom openai import OpenAI\n\n# General variables\nLIGHT_MODE = False\nFULL_MODE = False\nVERBOSE = True\nOUTPUT_FILE_BULEAN = False\nMASSIVE_MODE = False\n\n# LLM neighbour expansion\n\n# internal stored patterns: (I took it from rockyou.txt)\nBASIC_SUFIXS = ['1', '2', '123', '12', '3', '7', '13', '5', '4', '11', '!', '07', '23', '22', '01', '21', '8', '14', '10', '08', '6', '06', '9', '15', '16', '69', '18', '17', '24', '05', '.', '09', '88', '19', '25', '20', '03', '0', '04', '27', '89', '02', '99', '26', '101', '77', '1234', '28', '33', '00', '2007', '92', '87', '93', '2006', '*', '29', '94', '90', '2008', '91', '95', '86', '55', '30', '666', '143', '31', '96', '85', '44', '32', '007', '34', '4ever', '84', '45', '#1', '2005', '78', '98', '66', '83', '82', '97', '1994', '79', '100', '1992', '1993', '81', '4life', '4eva', '12345', '1995', '1991', '777', '1990', '420', '76', '56', '111', '1989', '2000', '1987', '321', '2009', '67', '80', '75', '2004', '1996', '42', '1988', '35', '74', '72', '1986', '1985', '001', '36', '73', '54', '2003', '456', '50', '!!', '333', '68', '@', '1984', '64', '37', '65', '40', '71', '2002', '4u', '123456', '43', '555', '911', '1997', '52', '?', '999', '1983', '1982', '47', '$', '57', '2001', '41', '@hotmail.com', '1980', '38', '4me', '1981', '63', '46', '70', '2010', '58', '48', '222', '51', '62', '1979', '121', '619', '53', '789', '59', '39', '112', '1998', '1978', '000', '888', '49', '**', '247', '234', '61', '60', '..', '213', '1977', '1212', '200', '159', '1999', '@yahoo.com', '1976', '182', '786', '1!', '.com', '<3', '1975', ')', '125', '187', '214', '2k7', '147', '...', '1974', '.1', '102', '1973', '!!!', '4e', '123456789', '411', '212', '6969', '1010', '305', '124', '012', '1972', '345', '360', '1969', '009', '316', '1970', '313', '4lyf', '711', '210', '808', '122', '1313', '987', '311', '120', '#', '1971', '444', '369', '1000', '008', '500', '2012', '323', '2011', '211', '1111', '246', '215', ',', '300', '135', '567', '117', '003', '103', '113', '1968', '1122', '225', '713', '132', '209', '510', '002', '520', '1221', '310', '223', '105', '~', '127', '100pre', '110', '1967', '818', '011', '1213', '1012', '202', '312', '128', '109', '+', '108', '126', '098', '1966', '2k6', '1965', '909', '1.', '118', '1020', '3000', '115', '678', '714', '415', '1964', '013', '1123', '107', '718', '129', ']', '831', '010', '2121', '4l', '005', '145', '314', '224', '104', '2525', '131', ';', '221', '626', '1314', '2020', '357', '4lyfe', '114', '318', '1210', '1223', '916', '1023', '1230', '106', '900', '216', '006', '116', '1011', '2323', '201', '2468', '4321', '119', '504', '3r', '1963', '1214', '217', '315', '2u', '512', '1224', '412', '0123', '1231', '1022', '1121', '1013', '1001', '258', '890', '134', '150', '220', '421', '1021', '1220', '1024', '1218', '1215', '317', '199', '521', '1216', '***', '303', '515', '004', '707', '$$', '206', '1014', '219', '1025', '1211', '1962', '218', '320', '1960', '1217', '413', '4444', '727', '1205', '1225', '`', '912', '812', '410', '0n', '813', '227', '2k', '014', '100%', '1206', '231', '1228', '505', '1029', '7777', '0000', '1017', '1015', '1107', '133', '1112', '325', '130', '513', '4LIFE', '324', '@1', '1016', '511', '1018', '423', '180', '1026', '021', '1125', '1031', '1028', \"'\", '1203', '1204', '1104', '023', '2k8', '612', '400', '721', '805', '1105', '2112', '1124', '1120', '4you', '525', '1207', '228', '205', '913', '2222', '2013', '#2', '1103', '1202', '1961', '1027', '617', '1106', '1019', '1127', '717', '1227', '156', '250', '4evr', '1208', '712', '600', '1219', '254', '1414', '017', '226', '408', '925', '723', '322', '1959', '137', '817', '319', '2424', '151', '809', '910', '232', '/', '203', '1229', '414', '326', '327', '616', '1515', '1226', '1030', '516', '1*', '1201', '2x', '365', '144', '1129', '123!', '623', '1209', '523', '611', '1126', '1005', '9999', '1128', '=', '1004', '!1', '1102', '710', '1002', '654', '1101', '613', '419', '1108', '422', '921', '198', '1130', '425', '123.', '923', '915', '169', '615', '015', '416', '#3', '951', '610', '141', '190', '816', '328', '1958', '811', '720', '016', '828', '426', '702', '919', '191', '1a', '522', '1007', '501', '018', '823', '189', '715', '8888', '918', '54321', '716', '256', '1003', '424', '1234567', '963', '138', '@123', '207', '427', '2345', '787', '5150', '852', '242', '914', '621', '331', '4EVER', '741', '637', '614', '.123', '562', '252', '920', '301', '1109', '1222', '153', '330', '1e', '417', '1006', '530', '800', '0506', '1957', '*1', '245', '1956', '517', '622', '155', '235', '753', '514', '329', ':)', '1113', '0101', '157', '821', '722', '810', '5678', '429', '2526', '724', '527', '024', '069', '524', '418', '0607', '208', '922', '624', '142', '168', '152', '2me', '0808', '1008', '929', '561', '2b', '700', '1717', '928', '815', '233', '518', '136', '177', '0708', '625', '0102', '725', '901', '022', '822', '917', '0909', '519', '334', '526', '248', '183', '731', '927', '531', '1117', '167', '602', '1114', '1818', '814', '5555', '529', '019', '620', '1n', '1616', '1955', '824', '618', '%', '1009', '192', '719', '503', '924', '1919', '229', '1st', '@aol.com', '926', \"'s\", '820', '430', '0707', '528', '188', '181', '4EVA', '989', '432', '1412', '204', '404', '1110', '0406', '304', '428', '5000', '0405', '825', '0809', '3s', '??', '628', '0204', '281', '2212', '3d', '0205', '197', '0202', '1115', '1954', '726', '728', '237', '0505', '757', '1116', '302', '140', '954', '559', '601', '747', '1516', '405', '730', '0305', '243', '146', '154', '509', '729', '627', '0306', '1415', '\"', '350', '629', '1324', '696', '0507', '0711', '0214', '253', '269', '407', '0407', '0304', '306', '4U', '650', '2310', '171', '236', '2529', '630', '1905', '239', '2528', '450', '1s', '2527', '139', '025', '195', '&', '0303', '123*', '1118', '454', '0606', '2530', '0203', '876', '930', '178', \"\\\\\\\\'\", '2210', '0107', '0404', '027', '0408', '1907', '819', '0812', '409', '158', '908', '543', '401', '230', '0210', '1312', '0308', '307', '1love', '240', '0412', '1369', '1310', '1953', '826', '829', '2!', '165', '2105', '161', '606', '1234567890', '160', '148', '904', '0311', '830', '0307', '0103', '2211', '2014', '193', '.12', '0110', '308', '827', '1307', '0420', '0206', '1119', '0207', '@@', '0911', '0212', '149', '990', '0105', '2123', '.2', '255', '309', '(L)', '241', '3333', '801', '0912', '185', '1432', '0104', '6666', '0987', '175', '163', '502', '1950', '671', '0106', '0208', '765', '251', '337', '1908', '170', '445', '166', '028', '173', '257', '3y', '031', '2107', '1888', '2524', '123123', '196', '&me', '1402', '0608', '2311', '1331', '!@#', '1903', '1305', '0312', '1235', '1@', '956', '174', '2312', '0509', '275', '2523', '0508', '172', '0512', '1311', '1306', '1952', '1200', '90210', '1512', '1408', '1233', '026', '1411', '2727', '1920', '978', '184', '5683', '1690', '0810', '2510', '244', '0709', '565', '2410', '667', '238', '090', '0108', '164', '12345678', '55555', '4u2', '0411', '1912', '#7', '3n', '2412', '2205', '1812', '1904', '0811', '2103', '402', '0612', '0309', '973', '0907', '336', '14344', '1410', '123321', '1906', '1323', '289', '903', '\\\\\\\\', '0211', '0209', '1405', '2106', '2828', '0712', '803', '2580', '2626', '267', '0321', '1308', '1718', '>', '2207', '1304', '262', '4ev', '077', '179', '343', '2531', '2110', '3030', '1508', '1407', '12!', '2203', '162', '0x', '585', '0906', '176', '1821', '1606', '2303']\nBASIC_PREFIXS = ['1', '2', '4', '123', '3', '*', '12', '7', '5', '8', '6', '13', '11', '143', '9', '19', '@', '(', '10', '14', '0', '22', '23', '21', '$', '!', '#1', '20', '15', '24', '18', '17', '16', '1234', '69', '.', '25', '01', '27', 'i', '07', '26', '**', '28', '06', '29', '08', '30', '~', '00', '05', '123456', '88', '99', '12345', '02', '03', '100', '04', '31', '09', '[', '666', '33', '77', '#', 'sk8', '50', 'ms.', 'mr.', '123456789', '1994', 'i<3', '100%', 'mz.', '<', '89', 'l0', '44', '1992', '1993', '420', '32', '1995', '55', '2007', '101', '34', '321', '1991', '007', '92', ',', 'm1', '2006', '87', '95', '1989', '\"', '<3', '1996', '1990', '98', 'no1', '93', '1987', '777', 'm0', '94', 'c0', '90', '66', '2008', '45', ';', 'r0', '91', '96', 'il0', '86', '1988', 'my1', 'ih8', '78', '97', 'my', 'h0', '..', '+', '!!', '111', 'p0', 'l1', 'j0', '56', 'b1', 'm3', '85', '1986', '1985', '52', 'd3', '35', '42', 'k1', '/', 's3', '2005', '84', '40', '79', '`', '82', '619', '***', 's0', '54', 'p1', 'b3', '76', 'te', '36', '74', '67', 'a1', 'g0', 'hi5', '=', '83', 'd0', '1997', '911', '333', '1984', 'b0', '49', 's1', '456', 'd1', '68', '555', 'm@', '80', '72', '43', 'j.', '?', '$$', '...', 'j3', '789', 'h3', '999', '187', '37', '1983', '75', '57', 'n0', '41']\nNUMERIC_PATTERNS = ['1', '2', '4', '3', '123', '7', '12', '5', '0', '8', '13', '6', '9', '11', '23', '22', '10', '14', '07', '21', '01', '15', '08', '06', '16', '18', '69', '17', '24', '05', '19', '09', '20', '25', '88', '03', '00', '27', '04', '02', '33', '89', '26', '99', '1234', '28', '77', '101', '92', '2007', '93', '87', '29', '94', '2006', '143', '90', '91', '30', '95', '2008', '55', '31', '100', '86', '666', '34', '44', '32', '96', '85', '45', '007', '84', '98', '1994', '78', '66', '2005', '1992', '1993', '83', '82', '12345', '97', '1991', '1995', '79', '1990', '81', '1989', '56', '777', '1987', '76', '420', '321', '111', '35', '67', '1996', '80', '2000', '1988', '42', '75', '123456', '50', '2009', '74', '2004', '1986', '72', '54', '36', '456', '1985', '73', '43', '1984', '64', '2003', '68', '37', '40', '333', '001', '52', '65', '47', '41', '71', '1997', '57', '1983', '555', '2002', '999', '1982', '911', '38', '1980', '2001', '46', '63', '70', '1981', '48', '51', '53', '58', '789', '62', '39', '2010', '59', '619', '49', '1979', '222', '121', '000', '1998', '112', '1978', '123456789', '60', '61', '888', '234', '159', '1212', '247', '200', '1977', '213', '786', '1999', '125', '182', '1976', '187', '1975', '147', '214', '1974', '1973', '102', '305', '1010', '6969', '124', '1972', '212', '360', '987', '1000', '411', '345', '1969', '012', '808', '313', '311', '210', '1313', '1970', '369', '500', '120', '300', '316', '711', '122', '1971', '009', '1111', '444', '323', '520', '135', '2012', '246', '211', '2011', '1122', '567', '215', '103', '008', '113', '1968', '117', '225', '510', '310', '209', '1221', '110', '132', '2468', '713', '105', '003', '127', '1213', '1967', '312', '002', '223', '1012', '109', '128', '011', '818', '1966', '108', '126', '098', '202', '118', '2525', '1020', '1123', '104', '831', '1965', '115', '357', '010', '2121', '107', '714', '1314', '145', '909', '415', '900', '129', '678', '314', '224', '1964', '318', '2020', '1210', '114', '131', '2323', '718', '3000', '504', '013', '106', '4321', '1223', '1230', '221', '626', '1023', '201', '116', '005', '1011', '150', '916', '216', '512', '119', '0123', '1214', '515', '006', '412', '1963', '1224', '315', '258', '0000', '134', '217', '220', '812', '1121', '199', '890', '1001', '1231', '1024', '521', '1021', '400', '1022', '1013', '4444', '303', '1215', '1220', '421', '250', '1234567', '1216', '206', '320', '1218', '317', '707', '325', '218', '1025', '1962', '7777', '413', '1211', '1014', '219', '410', '133', '1225', '130', '600', '1029', '1205', '1960', '813', '1217', '004', '1206', '1015', '231', '1228', '1112', '912', '227', '180', '1107', '505', '654', '727', '014', '1017', '324', '1120', '1204', '1031', '513', '2222', '1016', '423', '1028', '2112', '1026', '805', '205', '1203', '156', '1018', '963', '1105', '1125', '1414', '228', '511', '1124', '021', '408', '612', '1104', '525', '2424', '1208', '232', '254', '151', '1202', '1027', '809', '319', '1103', '144', '1207', '1515', '1106', '1127', '322', '721', '913', '203', '414', '226', '54321', '137', '023', '2013', '1005', '1019', '800', '1219', '1227', '910', '1961', '326', '717', '925', '617', '951', '1229', '723', '1030', '611', '1129', '1209', '700', '817', '1959', '1226', '327', '712', '365', '1004', '710', '616', '017', '9999', '1201', '1102', '5150', '1128', '852', '198', '425', '191', '1002', '523', '623', '426', '141', '350', '1101', '516', '256', '753', '1126', '422', '419', '8888', '741', '155', '1108', '1130', '169', '787', '190', '1234567890', '501', '252', '242', '613', '915', '610', '2014', '2015', '2016', '2017', '2018', '2019', '2021', '2021', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030']\nSYMBOLIC_PATTERNS = ['.', '-', '!', '@', '*', '/', '#', '&', ',', '$', '+', '=', '?', '(', ')', '**', '!!', ';', '<', '..', \"'\", ']', '%', '\"', '~', '...', '[', '`', '=\"', \"\\\\\\\\'\", ':', '!!!', '$$', '***', '^', '--', '@@', '//', '>', '++', '??', '!@', '\\\\\\\\', ':)', 'ื', '://', '!@#', '##', \"\\\\\\\\\\\\\\\\\\\\\\\\'\", '.,', '{', '\\\\\\\\\\\\\\\\', ',.', '}', '$$$', '><', ',,', '()', 'ั', '้', '/*', '^^', 'ุ', '@#', 'ึ', '+-', '&&', '???', '@@@', '*/', 'ิ', '|', ';;', 'ี', '****', '==', '@!', '....', '!*', '[]', ',./', '---', '=]', '/*-', '@$', '=)', '!!!!', '.-', '#!', '~~', ',]', '´', '!@#$', '-=', '*-', ')(', '+++', '))', '?!', '=-']\n\n\ndef print_banner():\n ascii_art = \"\"\" \n\n .-: \n -*%%%#+. \n =#%%%%%%%%+. \n .*%%%%%%%%%%%#- \n :#%%%%%%%%%%%%%#= \n :#*%%%#=:..=*%%%*#= \n ##%%+: .=#@#%: \n =%%*. .=%%# \n #%= :#%: \n .@= . .:%= \n #.:- :- *: \n ...:%= :%+ :. - \n :%+. +%+ -%#: -#: *: \n ..::--:..=+: .++:.:+=.:#= = \n .-=+++++=-:::: .:. .. .+#- =- \n -+=-:...::-=+++=:. .-*#+ *+ : \n :-=++++=-:. ... .:=#%*- -#- -. \n .=+=-:..........:=+###+- .=#+. =:. \n :. .:::. .-+#%#*=: .-*#+. -*:.: \n :-:. .-#%#+-. .-+#*+: -*= :- \n .:. .+%#+: :=+*+-. :=+=. -- \n =%#- :=++-: .-+=: :-. \n +%- .-==-. .-==: :-: \n =*. :=-. .:--: .:-: \n :+ --. .:-: .::. \n : :: .:. .:. \n :. :. ... \n .. :. .. \n \"\"\"\n print(ascii_art)\n print(\"Welcome to DICMA. The Dictionary Maker: \\n\")\n\ndef verbose_print(input_string):\n global VERBOSE\n if VERBOSE == True:\n print(input_string)\n \ndef detec_if_file_or_not(input_to_check):\n path_ = input_to_check\n if os.path.isfile(path_):\n return True\n else:\n return False\n\ndef system_detection():\n if os.name == \"nt\":\n return \"windows\"\n else:\n return \"linux\"\n \ndef get_total_ram():\n system = platform.system()\n\n if system == \"Linux\":\n try:\n with open(\"/proc/meminfo\", \"r\") as f:\n for line in f:\n if line.startswith(\"MemTotal:\"):\n parts = line.split()\n ram_kb = int(parts[1])\n return round(ram_kb / (1024 ** 2), 2) # Convert kB to GB\n except Exception as e:\n print(\"Error reading /proc/meminfo:\", e)\n\n elif system == \"Windows\":\n try:\n kernel32 = ctypes.windll.kernel32\n c_ulonglong = ctypes.c_ulonglong\n\n class MEMORYSTATUSEX(ctypes.Structure):\n _fields_ = [\n ('dwLength', ctypes.c_ulong),\n ('dwMemoryLoad', ctypes.c_ulong),\n ('ullTotalPhys', c_ulonglong),\n ('ullAvailPhys', c_ulonglong),\n ('ullTotalPageFile', c_ulonglong),\n ('ullAvailPageFile', c_ulonglong),\n ('ullTotalVirtual', c_ulonglong),\n ('ullAvailVirtual', c_ulonglong),\n ('sullAvailExtendedVirtual', c_ulonglong),\n ]\n\n memory = MEMORYSTATUSEX()\n memory.dwLength = ctypes.sizeof(MEMORYSTATUSEX)\n kernel32.GlobalMemoryStatusEx(ctypes.byref(memory))\n return round(memory.ullTotalPhys / (1024 ** 3), 2) # Convert bytes to GB\n except Exception as e:\n print(\"Error using ctypes on Windows:\", e)\n\n elif system == \"Darwin\": # macOS\n try:\n result = subprocess.run(\n [\"sysctl\", \"hw.memsize\"],\n capture_output=True, text=True\n )\n output = result.stdout\n if \"hw.memsize:\" in output:\n ram_bytes = int(output.split(\":\")[1].strip())\n return round(ram_bytes / (1024 ** 3), 2) # Convert bytes to GB\n except Exception as e:\n print(\"Error running sysctl on macOS:\", e)\n\n else:\n print(\"Unsupported operating system:\", system)\n\n return None\n \n \ndef is_a_valid_file(file_path, blocksize=512):\n try:\n with open(file_path, 'rb') as file_:\n chunk = file_.read(8192)\n chunk.decode('latin-1')\n return True\n\n except UnicodeDecodeError:\n return False\n except Exception:\n return False\n\ndef save_list_to_file(list_, filename):\n try:\n with open(filename, 'w', encoding='utf-8') as f:\n for item in list_:\n f.write(f\"{item}\\n\")\n verbose_print(f\"[+] Dictionary saved successfully to: {filename}\")\n except Exception as e:\n print(f\"Error saving dictionary: {e}\", file=sys.stderr)\n\ndef remove_accents(input_str):\n return ''.join(\n c for c in unicodedata.normalize('NFD', input_str)\n if unicodedata.category(c) != 'Mn'\n )\n\ndef ask_for_yes_or_no(question):\n while True:\n answer = input(question + \" (yes/no): \").strip().lower()\n if answer in [\"yes\", \"y\"]:\n return True\n elif answer in [\"no\", \"n\"]:\n return False\n else:\n print(\"Please, answer 'yes' or 'no'.\")\n \ndef normalize(text):\n return ''.join(\n c for c in unicodedata.normalize('NFKD', text)\n if not unicodedata.combining(c)\n )\n\ndef generate_usernames(person_name):\n parts = person_name.strip().split()\n if len(parts) == 0:\n return []\n if len(parts) == 1:\n return [normalize(parts[0])]\n\n def generate_combinations_light(name, surname):\n name = normalize(name)\n surname = normalize(surname)\n f_name = name[0]\n f_surname = surname[0]\n return [\n f\"{name}\",\n f\"{surname}\",\n f\"{name}.{surname}\",\n f\"{name}_{surname}\",\n f\"{f_name}{surname}\",\n f\"{f_name}.{surname}\",\n f\"{name}{f_surname}\",\n f\"{name}.{f_surname}\",\n f\"{f_name}_{surname}\",\n f\"{surname}.{name}\",\n ]\n\n def generate_combinations(name, surname):\n name = normalize(name)\n surname = normalize(surname)\n first_let_name = name[0]\n first_let_surname = surname[0]\n return [\n f\"{name} {surname}\",\n f\"{name}\",\n f\"{name}{surname}\",\n f\"{first_let_name}{surname}\",\n f\"{name}{first_let_surname}\",\n f\"{name}.{surname}\",\n f\"{first_let_name}.{surname}\",\n f\"{name}.{first_let_surname}\",\n f\"{name}_{surname}\",\n f\"{first_let_name}_{surname}\",\n f\"{name}_{first_let_surname}\",\n f\"{name}-{surname}\",\n f\"{first_let_name}-{surname}\",\n f\"{name}-{first_let_surname}\",\n f\"{first_let_name}{first_let_surname}\",\n f\"{first_let_surname}{first_let_name}\",\n f\"{first_let_name}.{first_let_surname}\",\n f\"{first_let_surname}.{first_let_name}\",\n f\"{first_let_name}-{first_let_surname}\",\n f\"{first_let_surname}-{first_let_name}\",\n f\"{first_let_name}_{first_let_surname}\",\n f\"{first_let_surname}_{first_let_name}\",\n f\"{surname}\",\n f\"{surname}{name}\",\n f\"{surname}{first_let_name}\",\n f\"{surname}.{name}\",\n f\"{surname}.{first_let_name}\",\n f\"{surname}_{name}\",\n f\"{surname}_{first_let_name}\",\n f\"{surname}-{name}\",\n f\"{surname}-{first_let_name}\",\n ]\n\n # Name + surname\n if len(parts) == 2:\n name, surname = parts\n if LIGHT_MODE:\n return generate_combinations_light(name, surname)\n return generate_combinations(name, surname)\n\n # 3 words cases\n if len(parts) == 3:\n p1, p2, p3 = parts\n if LIGHT_MODE:\n p1, p2, p3 = normalize(p1), normalize(p2), normalize(p3)\n i1, i2, i3 = p1[0], p2[0], p3[0]\n combos = []\n\n # 2-word patterns for name + first surname\n combos.extend(generate_combinations_light(p1, p2))\n # 2-word patterns for name + second surname\n combos.extend(generate_combinations_light(p1, p3))\n\n # 3-word combined patterns\n combos.extend([\n p3, # second surname alone\n f\"{p1}.{p2}.{p3}\", # name.surname1.surname2\n f\"{p1}_{p2}_{p3}\", # name_surname1_surname2\n f\"{i1}{p2}{p3}\", # flastname1lastname2\n f\"{i1}.{p2}.{p3}\", # f.surname1.surname2\n f\"{i1}_{p2}_{p3}\", # f_surname1_surname2\n f\"{p1}{i2}{p3}\", # name.f_surname1.surname2\n f\"{p1}.{i2}.{p3}\", # name.f.surname2\n f\"{p1}{p2}{i3}\", # namesurname1f_surname2\n f\"{p1}.{p2}.{i3}\", # name.surname1.f\n f\"{i1}{i2}{i3}\", # three initials\n f\"{i1}.{i2}.{i3}\", # f.m.l\n f\"{i1}_{i2}_{i3}\", # f_m_l\n ])\n return list(dict.fromkeys(combos))\n combinations = []\n combinations.extend(generate_combinations(p1, p2)) # word1 + word2\n combinations.extend(generate_combinations(p1, p3)) # word1 + word3\n combinations.extend(generate_combinations(p2, p3)) # word2 + word3\n # normalizing\n p1 = normalize(p1)\n p2 = normalize(p2)\n p3 = normalize(p3)\n i1 = p1[0]\n i2 = p2[0]\n i3 = p3[0]\n # Specific formats for 3 words:\n combinations.extend([\n # Individual words\n f\"{p1}\", f\"{p2}\", f\"{p3}\",\n\n # Name + both surnames\n f\"{p1}{p2}{p3}\",\n f\"{p1}.{p2}.{p3}\",\n f\"{p1}_{p2}_{p3}\",\n f\"{p1}-{p2}-{p3}\",\n\n # First letter + surnames\n f\"{i1}{p2}{p3}\",\n f\"{i1}.{p2}.{p3}\",\n f\"{i1}_{p2}_{p3}\",\n f\"{i1}-{p2}-{p3}\",\n\n # Name + composed surname\n f\"{p1}{p2}-{p3}\",\n f\"{p1}.{p2}-{p3}\",\n f\"{p1}_{p2}-{p3}\",\n f\"{i1}{p2}-{p3}\",\n f\"{i1}.{p2}-{p3}\",\n f\"{i1}_{p2}-{p3}\",\n f\"{p1}-{p2}{p3}\",\n f\"{p1}-{p2}.{p3}\",\n\n # Partial first letters (various separators)\n f\"{i1}{i2}{p3}\", f\"{i1}.{i2}.{p3}\", f\"{i1}_{i2}_{p3}\", f\"{i1}-{i2}-{p3}\",\n f\"{i1}{p2}{i3}\", f\"{i1}.{p2}.{i3}\", f\"{i1}_{p2}_{i3}\", f\"{i1}-{p2}-{i3}\",\n f\"{p1}{i2}{p3}\", f\"{p1}.{i2}.{p3}\", f\"{p1}_{i2}_{p3}\", f\"{p1}-{i2}-{p3}\",\n f\"{p1}{p2}{i3}\", f\"{p1}.{p2}.{i3}\", f\"{p1}_{p2}_{i3}\", f\"{p1}-{p2}-{i3}\",\n\n # 3-initials (name-surname1-surname2)\n f\"{i1}{i2}{i3}\", f\"{i1}.{i2}.{i3}\", f\"{i1}-{i2}-{i3}\", f\"{i1}_{i2}_{i3}\",\n # 3-initials (surname2-surname1-name)\n f\"{i3}{i2}{i1}\", f\"{i3}.{i2}.{i1}\", f\"{i3}-{i2}-{i1}\", f\"{i3}_{i2}_{i1}\",\n # 3-initials (surname1-name-surname2)\n f\"{i2}{i1}{i3}\", f\"{i2}.{i1}.{i3}\", f\"{i2}-{i1}-{i3}\", f\"{i2}_{i1}_{i3}\",\n # 3-initials (surname1-surname2-name)\n f\"{i2}{i3}{i1}\", f\"{i2}.{i3}.{i1}\", f\"{i2}-{i3}-{i1}\", f\"{i2}_{i3}_{i1}\",\n\n # Alternative surname orders\n f\"{p3}{p2}{p1}\", f\"{p3}.{p2}.{p1}\", f\"{p3}_{p2}_{p1}\", f\"{p3}-{p2}-{p1}\",\n f\"{p1}{p3}{p2}\", f\"{p1}.{p3}.{p2}\", f\"{p1}_{p3}_{p2}\", f\"{p1}-{p3}-{p2}\",\n\n # Mixed initial + 2 full words (alternate orders)\n f\"{i1}{p3}{p2}\", f\"{i1}.{p3}.{p2}\", f\"{i1}_{p3}_{p2}\", f\"{i1}-{p3}-{p2}\",\n f\"{i2}{p3}{p1}\", f\"{i2}.{p3}.{p1}\", f\"{i2}_{p3}_{p1}\", f\"{i2}-{p3}-{p1}\",\n f\"{i3}{p1}{p2}\", f\"{i3}.{p1}.{p2}\", f\"{i3}_{p1}_{p2}\", f\"{i3}-{p1}-{p2}\",\n\n # Full word + initial + full word (alternate orders)\n f\"{p3}{i1}{p2}\", f\"{p3}.{i1}.{p2}\", f\"{p3}_{i1}_{p2}\", f\"{p3}-{i1}-{p2}\",\n f\"{p1}{i3}{p2}\", f\"{p1}.{i3}.{p2}\", f\"{p1}_{i3}_{p2}\", f\"{p1}-{i3}-{p2}\",\n f\"{p2}{i3}{p1}\", f\"{p2}.{i3}.{p1}\", f\"{p2}_{i3}_{p1}\", f\"{p2}-{i3}-{p1}\",\n ])\n return list(dict.fromkeys(combinations))\n print(\"[!] Unsupported names -> \" + str(person_name))\n return []\n\n\n\ndef normalize_list(input_):\n file_or_not = detec_if_file_or_not(input_)\n if file_or_not == True:\n with open(input_, 'r', encoding='utf-8') as file_:\n words_list = [line.strip() for line in file_ if line.strip()]\n return words_list\n else:\n raw_list = input_.strip().split(',')\n words_list = [word.strip() for word in raw_list if word.strip()]\n return words_list\n\ndef process_file_user(file_name, output_file_name):\n global OUTPUT_FILE_BULEAN\n with open(file_name, 'r', encoding='utf-8') as file_:\n if OUTPUT_FILE_BULEAN == False:\n for line_ in file_:\n line_ = line_.strip()\n if not line_:\n continue # Omitir líneas vacías\n combinations = generate_usernames(line_)\n for element in combinations:\n print(element)\n else:\n complet_list = []\n for line_ in file_:\n line_ = line_.strip()\n if not line_:\n continue \n combinations = generate_usernames(line_)\n for element in combinations:\n complet_list.append(element)\n save_list_to_file(complet_list, output_file_name) \n \ndef process_input_user(input_, output_file_name):\n global OUTPUT_FILE_BULEAN\n raw_list = input_.strip().split(',')\n people_list = [name.strip() for name in raw_list if name.strip()]\n final_list = []\n if OUTPUT_FILE_BULEAN == False:\n for name in people_list:\n final_list += generate_usernames(name) \n for element in final_list:\n print(element) \n else:\n for name in people_list:\n final_list += generate_usernames(name) \n save_list_to_file(final_list, output_file_name)\n \ndef process_passwd(words_list, output_file_name):\n global OUTPUT_FILE_BULEAN\n global FULL_MODE\n global LIGHT_MODE\n verbose_print(\"[+] Creating dictionary.\")\n \n # Checking for massive mode:\n if len(words_list) >= 2 and FULL_MODE == True:\n massive_mode(words_list, output_file_name)\n sys.exit(0)\n if len(words_list) >= 10 and LIGHT_MODE == False:\n massive_mode(words_list, output_file_name)\n sys.exit(0) \n if len(words_list) >= 100:\n massive_mode(words_list, output_file_name)\n sys.exit(0)\n\n final_list = []\n if OUTPUT_FILE_BULEAN == False:\n for word in words_list:\n final_list += generate_password_list(word, FULL_MODE, LIGHT_MODE) \n for element in final_list:\n print(element)\n else:\n for word in words_list:\n final_list += generate_password_list(word, FULL_MODE, LIGHT_MODE)\n save_list_to_file(final_list, output_file_name)\n \nCHUNK_SIZE = 300\nBATCH_GROUP_SIZE = 15\n\nDEFAULT_API_KEY = None\nDEFAULT_BASE_URL = \"https://api.deepseek.com\"\nDEFAULT_MODEL = \"deepseek-v4-flash\"\n\n\ndef _generate_config_template(path):\n content = (\n \"# DICMA - LLM configuration\\n\"\n \"# Pick one provider and fill in your API key if needed.\\n\"\n \"#\\n\"\n \"# === Ollama (local, no API key, no registration) ===\\n\"\n \"# 1. Install: brew install ollama\\n\"\n \"# 2. Start: ollama serve\\n\"\n \"# 3. Pull: ollama pull llama3.2:3b\\n\"\n \"#\\n\"\n 'API_KEY = \"ollama\"\\n'\n 'BASE_URL = \"http://localhost:11434/v1\"\\n'\n 'MODEL = \"llama3.2:3b\"\\n'\n \"\\n\"\n \"# === DeepSeek (recommended for best results) ===\\n\"\n \"# Sign up at https://platform.deepseek.com\\n\"\n \"# Requires credit (very cheap ~$0.01/request)\\n\"\n '# API_KEY = \"sk-\"\\n'\n '# BASE_URL = \"https://api.deepseek.com\"\\n'\n '# MODEL = \"deepseek-v4-flash\"\\n'\n \"\\n\"\n \"# === OpenAI ===\\n\"\n '# API_KEY = \"sk-\"\\n'\n '# BASE_URL = \"https://api.openai.com/v1\"\\n'\n '# MODEL = \"gpt-4o-mini\"\\n'\n )\n with open(path, \"w\", encoding=\"utf-8\") as f:\n f.write(content)\n\n\ndef _load_config(path):\n cfg = {}\n if not path or not os.path.isfile(path):\n return cfg\n with open(path, encoding=\"utf-8\") as f:\n for line in f:\n line = line.strip()\n if not line or line.startswith(\"#\"):\n continue\n m = re.match(r'^(\\w+)\\s*=\\s*[\"\\']?(.+?)[\"\\']?\\s*$', line)\n if m:\n cfg[m.group(1)] = m.group(2)\n return cfg\n\n\ndef _resolve_config(args):\n config = _load_config(args.config)\n\n api_key = (\n args.api_key\n or os.getenv(\"LLM_API_KEY\")\n or os.getenv(\"OPENAI_API_KEY\")\n or config.get(\"API_KEY\")\n or DEFAULT_API_KEY\n )\n base_url = (\n args.base_url\n or os.getenv(\"LLM_BASE_URL\")\n or os.getenv(\"OPENAI_BASE_URL\")\n or config.get(\"BASE_URL\")\n or DEFAULT_BASE_URL\n )\n model = (\n args.model\n or os.getenv(\"LLM_MODEL\")\n or config.get(\"MODEL\")\n or DEFAULT_MODEL\n )\n if not api_key:\n print(\n \"Error: no API key provided. Use --api-key, LLM_API_KEY env var, \"\n \"or a config file.\",\n file=sys.stderr,\n )\n sys.exit(1)\n return api_key, base_url, model\n\n\ndef _parse_words(raw):\n try:\n return json.loads(raw).get(\"words\", [])\n except json.JSONDecodeError:\n pass\n raw_fixed = raw.rstrip() + '\"]}'\n try:\n return json.loads(raw_fixed).get(\"words\", [])\n except json.JSONDecodeError:\n pass\n matches = re.findall(r'\"([^\"]+)\"', raw)\n return [m for m in matches if len(m) >= 2]\n\n\ndef _parse_words_batch(raw, input_words):\n result = {w: [] for w in input_words}\n try:\n data = json.loads(raw).get(\"words\", {})\n if isinstance(data, dict):\n for w, vals in data.items():\n w_lower = w.strip().lower()\n if w_lower in result and isinstance(vals, list):\n result[w_lower].extend(\n [v.strip().lower() for v in vals if isinstance(v, str)]\n )\n return result\n except json.JSONDecodeError:\n pass\n raw_fixed = raw.rstrip() + '\"}'\n try:\n data = json.loads(raw_fixed).get(\"words\", {})\n if isinstance(data, dict):\n for w, vals in data.items():\n w_lower = w.strip().lower()\n if w_lower in result and isinstance(vals, list):\n result[w_lower].extend(\n [v.strip().lower() for v in vals if isinstance(v, str)]\n )\n return result\n except json.JSONDecodeError:\n pass\n for word in input_words:\n escaped = re.escape(word)\n matches = re.findall(rf'\"{escaped}\"\\s*:\\s*\\[(.*?)(?:\\]|\\Z)', raw)\n for block in matches:\n vals = re.findall(r'\"([^\"]+)\"', block)\n result[word].extend([v.strip().lower() for v in vals if len(v) >= 2])\n return result\n\n\ndef _handle_api_error(e):\n msg = str(e).lower()\n body = getattr(e, \"body\", None) or {}\n\n if isinstance(body, dict):\n inner = body.get(\"error\", body.get(\"message\", \"\"))\n msg += \" \" + str(inner).lower()\n\n if any(x in msg for x in (\"400\", \"invalid_request_error\", \"model name\", \"model names\")):\n print(f\"[-] Invalid model or request: {e}\", file=sys.stderr)\n print(\" Check MODEL in config.txt or --model argument.\", file=sys.stderr)\n sys.exit(1)\n\n if any(x in msg for x in (\"401\", \"unauthorized\", \"invalid api key\", \"incorrect api key\")):\n print(\"[-] Authentication failed: invalid or missing API key.\", file=sys.stderr)\n print(\" Check API_KEY in config.txt or --api-key argument.\", file=sys.stderr)\n sys.exit(1)\n\n if any(x in msg for x in (\"402\", \"insufficient\", \"quota\", \"billing\", \"balance\", \"payment\")):\n print(\"[-] Insufficient quota or billing issue.\", file=sys.stderr)\n print(\" Check your account balance at the provider.\", file=sys.stderr)\n sys.exit(1)\n\n if any(x in msg for x in (\"403\", \"permission\", \"forbidden\", \"access denied\")):\n print(\"[-] Permission denied. Your API key may not have access to this model.\", file=sys.stderr)\n print(\" Check MODEL in config.txt and your API key permissions.\", file=sys.stderr)\n sys.exit(1)\n\n if any(x in msg for x in (\"404\", \"not found\", \"does not exist\")):\n print(f\"[-] Model not found. Check MODEL in config.txt.\", file=sys.stderr)\n sys.exit(1)\n\n if any(x in msg for x in (\"connection\", \"timeout\", \"refused\", \"unreachable\", \"resolve\", \"network\")):\n print(\"[-] Could not connect to the LLM API.\", file=sys.stderr)\n print(\" Check your internet connection and BASE_URL in config.txt.\", file=sys.stderr)\n print(\" If using Ollama, make sure 'ollama serve' is running.\", file=sys.stderr)\n sys.exit(1)\n\n if any(x in msg for x in (\"429\", \"rate limit\", \"too many requests\")):\n print(\"[-] Rate limited by the API. Retrying...\", file=sys.stderr)\n return False\n\n print(f\"[-] API error: {e}\", file=sys.stderr)\n raise\n\n\ndef _call_api(client, model, word, n):\n try:\n response = client.chat.completions.create(\n model=model,\n messages=[{\n \"role\": \"user\",\n \"content\": (\n f'List exactly {n} terms (lowercase, no spaces) with the '\n f'strongest semantic relationship to \"{word}\". Prioritize '\n f'synonyms, conceptually-related words, and terms from '\n f'the same domain or universe. Do NOT add numbers, '\n f'symbols, or character substitutions — just plain words. '\n f'Return ONLY a JSON object {{\"words\": [...]}}. '\n f'No markdown or explanation.'\n ),\n }],\n response_format={\"type\": \"json_object\"},\n temperature=0.8,\n max_tokens=8192,\n )\n return _parse_words(response.choices[0].message.content)\n except Exception as e:\n _handle_api_error(e)\n raise\n\n\ndef _call_api_batch(client, model, words, n):\n quoted = \", \".join(f'\"{w}\"' for w in words)\n try:\n response = client.chat.completions.create(\n model=model,\n messages=[{\n \"role\": \"user\",\n \"content\": (\n f'For each of these words: [{quoted}], list exactly {n} '\n f'terms (lowercase, no spaces) with the strongest semantic '\n f'relationship. Do NOT add numbers, symbols, or character '\n f'substitutions — just plain words. Return ONLY a JSON '\n f'object: {{\"words\": {{\"word1\": [...], \"word2\": [...], ...}}}}. '\n f'No markdown or explanation.'\n ),\n }],\n response_format={\"type\": \"json_object\"},\n temperature=0.8,\n max_tokens=8192,\n )\n return _parse_words_batch(\n response.choices[0].message.content, words\n )\n except Exception as e:\n _handle_api_error(e)\n raise\n\n\ndef _chunks(lst, size):\n for i in range(0, len(lst), size):\n yield lst[i:i + size]\n\n\ndef _llm_neighbours(client, model, word, n):\n import time\n all_words = []\n stale = 0\n call_num = 0\n t0 = time.time()\n for _ in range(n):\n needed = n - len(all_words)\n if needed <= 0:\n break\n if needed <= 50 and call_num == 0:\n batch_n = min(needed, CHUNK_SIZE)\n else:\n batch_n = min(max(int(needed * 2), 50), CHUNK_SIZE)\n before = len(all_words)\n call_num += 1\n batch = _call_api(client, model, word, batch_n)\n if not batch:\n for attempt in range(1, 3):\n verbose_print(\n f\"[!] L1 '{word}': call {call_num} \"\n f\"returned 0 words, retry {attempt}/2\"\n )\n batch = _call_api(client, model, word, batch_n)\n if batch:\n break\n for w in batch:\n cleaned = w.strip().lower()\n if cleaned and cleaned not in all_words:\n all_words.append(cleaned)\n new_count = len(all_words) - before\n verbose_print(\n f\"[+] L1 '{word}': call {call_num} ({batch_n} req, \"\n f\"needed {needed}) → {len(batch)} returned, {new_count} new. \"\n f\"Total: {len(all_words)}/{n}\"\n )\n if call_num >= 3:\n verbose_print(\n f\"[!] L1 '{word}': stopping after {call_num} calls \"\n f\"({len(all_words)}/{n} words)\"\n )\n break\n if len(all_words) == before:\n stale += 1\n if stale >= 3:\n break\n else:\n stale = 0\n elapsed = time.time() - t0\n verbose_print(\n f\"[+] L1 '{word}': done — {len(all_words)} words, \"\n f\"{call_num} call(s), {elapsed:.1f}s\"\n )\n return all_words[:n]\n\n\ndef ml_expand_words(client, model, input_words, n1, n2, n3):\n seen = set(input_words)\n\n # ---------- level 1 ----------\n level1 = []\n for word in input_words:\n try:\n neighbours = _llm_neighbours(client, model, word, n1)\n level1.append((word, neighbours))\n for nb in neighbours:\n cleaned = nb.strip().lower()\n if cleaned and cleaned not in seen:\n seen.add(cleaned)\n except Exception as exc:\n print(f\"Error L1 '{word}': {exc}\", file=sys.stderr)\n\n if n2 <= 0:\n return seen\n\n # ---------- level 2 ----------\n all_l1_words = []\n for parent, siblings in level1:\n for s in siblings:\n if s != parent and s not in all_l1_words:\n all_l1_words.append(s)\n\n for group in _chunks(all_l1_words, BATCH_GROUP_SIZE):\n try:\n batch_result = _call_api_batch(client, model, group, n2)\n except Exception as exc:\n print(f\"Error L2 batch: {exc}\", file=sys.stderr)\n continue\n for word in group:\n for nb in batch_result.get(word, []):\n cleaned = nb.strip().lower()\n if cleaned and cleaned not in seen:\n seen.add(cleaned)\n\n if n3 <= 0:\n return seen\n\n # ---------- level 3 ----------\n all_l2_words = [w for w in seen if w not in input_words]\n\n for group in _chunks(all_l2_words, BATCH_GROUP_SIZE):\n try:\n batch_result = _call_api_batch(client, model, group, n3)\n except Exception as exc:\n print(f\"Error L3 batch: {exc}\", file=sys.stderr)\n continue\n for word in group:\n for nb in batch_result.get(word, []):\n cleaned = nb.strip().lower()\n if cleaned and cleaned not in seen:\n seen.add(cleaned)\n\n return seen\n\ndef worker_generate(word, FULL_MODE, LIGHT_MODE, queue, batch_size=200):\n try:\n batch = []\n for line in generate_password_list(word, FULL_MODE, LIGHT_MODE):\n batch.append(line)\n if len(batch) >= batch_size:\n queue.put('\\n'.join(batch))\n batch.clear()\n if batch:\n queue.put('\\n'.join(batch))\n except Exception as e:\n queue.put(f\"# Error with word '{word}': {e}\") \n\ndef worker_task(args):\n word, FULL_MODE, LIGHT_MODE, queue = args\n worker_generate(word, FULL_MODE, LIGHT_MODE, queue)\n\ndef massive_mode(list_, output_file_name):\n global LIGHT_MODE, FULL_MODE, OUTPUT_FILE_BULEAN\n\n verbose_print(\"[!] Massive mode ENABLED\")\n if not OUTPUT_FILE_BULEAN:\n verbose_print(\"[!] Massive mode printing to stdout (use -o to save to file).\")\n\n cpu_cores = multiprocessing.cpu_count()\n if FULL_MODE == True:\n ram = get_total_ram()\n verbose_print(f\"[i] {ram} GB RAM detected.\")\n if ram <= 31:\n cpu_cores = cpu_cores // 2\n if cpu_cores == 0:\n cpu_cores = 1\n if ram <= 15:\n verbose_print(\"[!] WARNING! Full mode + multicore could saturate RAM, crash, and go slower than expected. \\n[!] We will use just few cores... Go for a coffe.\")\n cpu_cores = cpu_cores // 4\n if cpu_cores == 0:\n cpu_cores = 1\n verbose_print(f\"[+] Using {cpu_cores} CPU cores\")\n\n output_size_lines = len(list_) * 900000\n if LIGHT_MODE == True:\n output_size_lines = len(list_) * 7700\n if FULL_MODE == True:\n output_size_lines = len(list_) * 5000000\n avg_line_size_bytes = 16\n estimated_size_bytes = output_size_lines * avg_line_size_bytes\n estimated_size_gb = round(estimated_size_bytes / (1024 ** 3), 2)\n verbose_print(\"[i] Expected file size -> \" + str(estimated_size_gb) + \" GB / \" + str(output_size_lines) + \" Lines (aprox.)\")\n\n manager = multiprocessing.Manager()\n queue = manager.Queue(maxsize=500)\n pool = multiprocessing.Pool(cpu_cores)\n args_list = [(word, FULL_MODE, LIGHT_MODE, queue) for word in list_]\n results = [pool.apply_async(worker_task, (args,)) for args in args_list]\n\n if OUTPUT_FILE_BULEAN:\n out_f = open(output_file_name, 'w', encoding='utf-8')\n else:\n out_f = sys.stdout\n\n try:\n processed_words = 0\n total_words = len(list_)\n\n while processed_words < total_words:\n try:\n chunk = queue.get(timeout=5)\n out_f.write(chunk + '\\n')\n except Exception:\n if all(r.ready() for r in results):\n while not queue.empty():\n out_f.write(queue.get() + '\\n')\n processed_words = total_words\n\n processed_words = sum(1 for r in results if r.ready())\n progress = processed_words / total_words * 100\n print(f\"\\r[+] Progress: {progress:.2f}%\", end='', flush=True)\n finally:\n if OUTPUT_FILE_BULEAN:\n out_f.close()\n\n pool.close()\n pool.join()\n if OUTPUT_FILE_BULEAN:\n print(f\"\\n[+] Finished. Output saved to {output_file_name}\")\n else:\n print(f\"\\n[+] Finished.\")\n\ndef generate_password_list(word, FULL_MODE, LIGHT_MODE):\n global amount_of_sufixs_used\n global amount_of_prefixs_used\n \n if LIGHT_MODE == True:\n amount_of_sufixs_used = amount_of_sufixs_used_light_mode\n amount_of_prefixs_used = amount_of_prefixs_used_light_mode\n\n # GENERATING BASIC PATTERN:\n basic_pattern = []\n word = str(word).lower()\n word_no_punctuation = remove_accents(word)\n \n basic_pattern.append(word)\n basic_pattern.append(word.upper())\n basic_pattern.append(word.capitalize())\n basic_pattern.append(word_no_punctuation)\n basic_pattern.append(word_no_punctuation.upper())\n basic_pattern.append(word_no_punctuation.capitalize()) \n\n basic_pattern = list(set(basic_pattern))\n \n transform_1 = [item.replace(\"a\", \"@\").replace(\"A\", \"@\") for item in basic_pattern]\n basic_pattern.extend(transform_1)\n transform_2 = [item.replace(\"o\", \"0\").replace(\"O\", \"0\") for item in basic_pattern]\n basic_pattern.extend(transform_2)\n if LIGHT_MODE == False:\n transform_3 = [item.replace(\"e\", \"€\").replace(\"E\", \"€\") for item in basic_pattern]\n basic_pattern.extend(transform_3)\n transform_4 = [item.replace(\"e\", \"3\").replace(\"E\", \"3\") for item in basic_pattern]\n basic_pattern.extend(transform_4)\n transform_5 = [item.replace(\"s\", \"$\").replace(\"S\", \"$\") for item in basic_pattern]\n basic_pattern.extend(transform_5)\n transform_6 = [item.replace(\"l\", \"1\").replace(\"L\", \"1\") for item in basic_pattern]\n basic_pattern.extend(transform_6)\n \n non_repeated_list = []\n for item in basic_pattern:\n if item not in non_repeated_list:\n non_repeated_list.append(item)\n \n # word + sufix\n word_sufixs = [a + b for a in basic_pattern for b in BASIC_SUFIXS[:amount_of_sufixs_used]]\n non_repeated_list.extend(word_sufixs)\n # prefix + word\n prefix_word = [a + b for a in BASIC_PREFIXS[:amount_of_prefixs_used] for b in basic_pattern]\n non_repeated_list.extend(prefix_word) \n # prefix + word + sufix\n prefix_word_sufixs = [a + b + c for a in BASIC_PREFIXS[:amount_of_prefixs_used//3] for b in basic_pattern for c in BASIC_SUFIXS[:amount_of_sufixs_used//3]]\n non_repeated_list.extend(prefix_word_sufixs)\n \n # EXTENDED MODE:\n if FULL_MODE == True:\n # word + number\n word_number = [a + b for a in basic_pattern for b in NUMERIC_PATTERNS[:amount_of_numericpat_used]]\n non_repeated_list.extend(word_number)\n # word + simbol\n word_simbol = [a + b for a in basic_pattern for b in SYMBOLIC_PATTERNS[:amount_of_symbolpat_used]]\n non_repeated_list.extend(word_simbol)\n # word + number + simbol\n word_number_simbol = [a + b + c for a in basic_pattern for b in NUMERIC_PATTERNS[:amount_of_numericpat_used] for c in SYMBOLIC_PATTERNS[:amount_of_symbolpat_used]]\n non_repeated_list.extend(word_number_simbol)\n # word + simbol + number\n word_simbol_number = [a + b + c for a in basic_pattern for b in SYMBOLIC_PATTERNS[:amount_of_symbolpat_used] for c in NUMERIC_PATTERNS[:amount_of_numericpat_used]]\n non_repeated_list.extend(word_simbol_number)\n # simbol + word\n simbol_word = [a + b for a in SYMBOLIC_PATTERNS[:amount_of_symbolpat_used] for b in basic_pattern]\n non_repeated_list.extend(simbol_word)\n # number + word\n number_word = [a + b for a in NUMERIC_PATTERNS[:amount_of_numericpat_used] for b in basic_pattern]\n non_repeated_list.extend(number_word)\n # simbol + word + number\n simbol_word_number = [a + b + c for a in SYMBOLIC_PATTERNS[:amount_of_symbolpat_used] for b in basic_pattern for c in NUMERIC_PATTERNS[:amount_of_numericpat_used]]\n non_repeated_list.extend(simbol_word_number)\n # number + word + simbol\n number_word_simbol = [a + b + c for a in NUMERIC_PATTERNS[:amount_of_numericpat_used] for b in basic_pattern for c in SYMBOLIC_PATTERNS[:amount_of_symbolpat_used]]\n non_repeated_list.extend(number_word_simbol)\n \n non_repeated_list = list(dict.fromkeys(non_repeated_list))\n return non_repeated_list\n\ndef extract_patterns(file_input):\n sufixs = []\n prefixs = []\n numbers = []\n symbols = []\n\n with open(file_input, 'r', encoding='utf-8', errors='ignore') as file_:\n for linea in file_:\n linea = linea.strip()\n \n match = re.search(r'(?:[^\\W\\d]|-){3,}', linea, flags=re.UNICODE)\n if match:\n concept_start = match.start()\n concept_end = match.end()\n\n prefix = linea[:concept_start].strip()\n sufix = linea[concept_end:].strip()\n\n if prefix:\n prefixs.append(prefix)\n if sufix:\n sufixs.append(sufix)\n verbose_print(\"[+] Prefix and Sufix successfully extracted\")\n\n found_numbers = re.findall(r'\\d+', linea)\n numbers.extend(found_numbers)\n verbose_print(\"[+] Numeric patterns successfully extracted\")\n\n found_symbols = re.findall(r'[^\\w\\s]+', linea, flags=re.UNICODE)\n symbols.extend(found_symbols)\n verbose_print(\"[+] Symbol patterns successfully extracted\")\n\n sorted_sufixs = [item for item, count in Counter(sufixs).most_common() if count >= 2]\n sorted_prefixs = [item for item, count in Counter(prefixs).most_common() if count >= 2]\n sorted_numbers = [item for item, count in Counter(numbers).most_common() if count >= 2]\n sorted_symbols = [item for item, count in Counter(symbols).most_common() if count >= 2]\n\n return sorted_sufixs, sorted_prefixs, sorted_numbers, sorted_symbols\n\n\ndef _ascii_chain(s):\n return \"\".join(c for c in s if ord(c) < 128)\n\n\ndef _build_append_rule(s):\n s = _ascii_chain(s)\n return \"\".join(f\"${c}\" for c in s) if s else \"\"\n\n\ndef _build_prepend_rule(s):\n s = _ascii_chain(s)\n return \"\".join(f\"^{c}\" for c in reversed(s)) if s else \"\"\n\n\ndef _leet_combos(light=False):\n atoms = [\"sa@\", \"so0\"]\n if not light:\n atoms.extend([\"se3\", \"ss$\", \"sl1\"])\n\n combos = [\"\"] # no leet\n n = len(atoms)\n for a in atoms:\n combos.append(a)\n for i in range(n):\n for j in range(i + 1, n):\n combos.append(f\"{atoms[i]} {atoms[j]}\")\n if not light:\n for i in range(n):\n for j in range(i + 1, n):\n for k in range(j + 1, n):\n combos.append(f\"{atoms[i]} {atoms[j]} {atoms[k]}\")\n for i in range(n):\n for j in range(i + 1, n):\n for k in range(j + 1, n):\n for m in range(k + 1, n):\n combos.append(f\"{atoms[i]} {atoms[j]} {atoms[k]} {atoms[m]}\")\n combos.append(\" \".join(atoms))\n return combos\n\n\ndef _leet_combos_simple(light=False):\n \"\"\"Returns empty, singles, pairs and triples (no quads).\"\"\"\n atoms = [\"sa@\", \"so0\"]\n if not light:\n atoms.extend([\"se3\", \"ss$\", \"sl1\"])\n combos = [\"\"]\n n = len(atoms)\n for a in atoms:\n combos.append(a)\n for i in range(n):\n for j in range(i + 1, n):\n combos.append(f\"{atoms[i]} {atoms[j]}\")\n if not light:\n for i in range(n):\n for j in range(i + 1, n):\n for k in range(j + 1, n):\n combos.append(f\"{atoms[i]} {atoms[j]} {atoms[k]}\")\n return combos\n\n\ndef generate_rules(suffixes, prefixes, light=False, full=False):\n if light:\n suf_lim = 120\n pre_lim = 35\n num_suf = 40\n num_pre = 20\n sym_lim = 20\n combo_pre = 8\n combo_suf = 15\n elif full:\n suf_lim = 9999\n pre_lim = 9999\n num_suf = 9999\n num_pre = 9999\n sym_lim = 9999\n combo_pre = 9999\n combo_suf = 9999\n else:\n suf_lim = 800\n pre_lim = 80\n num_suf = 200\n num_pre = 80\n sym_lim = 50\n combo_pre = 63\n combo_suf = 350\n\n cases = [\":\", \"l\", \"u\", \"c\"]\n leets = _leet_combos(light)\n leets_combo = _leet_combos_simple(light)\n\n sufs = list(dict.fromkeys(suffixes))[:suf_lim]\n prefs = list(dict.fromkeys(prefixes))[:pre_lim]\n nums = list(dict.fromkeys(NUMERIC_PATTERNS))[:num_suf]\n syms = list(dict.fromkeys(SYMBOLIC_PATTERNS))[:sym_lim]\n nums_pre = list(dict.fromkeys(NUMERIC_PATTERNS))[:num_pre]\n\n append_pats = []\n for s in sufs:\n chain = _build_append_rule(s)\n if chain:\n append_pats.append(chain)\n for n in nums:\n chain = _build_append_rule(n)\n if chain:\n append_pats.append(chain)\n for sym_val in syms:\n chain = _build_append_rule(sym_val)\n if chain:\n append_pats.append(chain)\n append_pats = list(dict.fromkeys(append_pats))\n\n prepend_pats = []\n for p in prefs:\n chain = _build_prepend_rule(p)\n if chain:\n prepend_pats.append(chain)\n for n in nums_pre:\n chain = _build_prepend_rule(n)\n if chain:\n prepend_pats.append(chain)\n for sym_val in syms:\n chain = _build_prepend_rule(sym_val)\n if chain:\n prepend_pats.append(chain)\n prepend_pats = list(dict.fromkeys(prepend_pats))\n\n combo_pats = []\n all_sufs_dedup = list(dict.fromkeys(suffixes))\n all_prefs_dedup = list(dict.fromkeys(prefixes))\n combo_prefs = all_prefs_dedup[:combo_pre] + nums_pre[:combo_pre]\n combo_sufs = all_sufs_dedup[:combo_suf] + nums[:combo_suf]\n for p in list(dict.fromkeys(combo_prefs)):\n prep = _build_prepend_rule(p)\n if not prep:\n continue\n for s in list(dict.fromkeys(combo_sufs)):\n app = _build_append_rule(s)\n if not app:\n continue\n combo_pats.append(f\"{prep} {app}\")\n\n rules = []\n # append + prepend: all cases × all leets\n for case in cases:\n for leet in leets:\n head = []\n if case != \":\":\n head.append(case)\n if leet:\n head.append(leet)\n\n for pat in append_pats:\n rule = \" \".join(head + [pat]) if head else pat\n rules.append(rule)\n for pat in prepend_pats:\n rule = \" \".join(head + [pat]) if head else pat\n rules.append(rule)\n\n # combos: all 3 cases × leets_combo (singles + pairs + triples)\n for case in [\"c\", \"l\", \"u\"]:\n for leet in leets_combo:\n head = [case]\n if leet:\n head.append(leet)\n for pat in combo_pats:\n rule = \" \".join(head + [pat]) if head else pat\n rules.append(rule)\n\n # identity\n if \":\" not in rules:\n rules.append(\":\")\n\n if full:\n return rules # skip dedup for full mode (too many rules)\n return list(dict.fromkeys(rules))\n\n\ndef main():\n global VERBOSE\n global LIGHT_MODE\n global FULL_MODE\n global OUTPUT_FILE_BULEAN\n global BASIC_SUFIXS\n global BASIC_PREFIXS\n global NUMERIC_PATTERNS\n global SYMBOLIC_PATTERNS\n\n if len(sys.argv) == 1:\n print_banner()\n\n # Generate config before argparse so it works on first run with no args\n config_path = \"config.txt\"\n for i, arg in enumerate(sys.argv):\n if arg == \"--config\" and i + 1 < len(sys.argv):\n config_path = sys.argv[i + 1]\n break\n if not os.path.isfile(config_path):\n _generate_config_template(config_path)\n print(f\"[i] Created {config_path} — edit it and paste your API key \"\n \"to use -jn or -p -n1 modes.\")\n\n output_file_name = ''\n\n parser = argparse.ArgumentParser(description=\"Welcome to DICMA. The Dictionary Maker:\")\n\n group = parser.add_mutually_exclusive_group(required=True)\n group.add_argument('-u', '--users', help='File with usernames, or usernames list: \"jony random,fahim jordan,...\"')\n group.add_argument('-p', '--password', help='file with words to \"passworize\", or list like: \"ibis,megacorp,...\"')\n group.add_argument('-jn', '--just-neighbours', help='Find semantic neighbours using an LLM API.')\n group.add_argument('-r', '--rules', action='store_true', help='Generate Hashcat rules from suffix/prefix patterns.')\n\n parser.add_argument('-l', '--light', action='store_true', help='Light mode, for small list (passwd mode).')\n parser.add_argument('-f', '--full', action='store_true', help='Full mode. Warning, the output could be very heavy (passwd mode).')\n parser.add_argument('-nv','--no-verbose', action='store_true', help='Remove any output except the dictionary itself (Errors will be shown anyway).')\n parser.add_argument('-d','--dictionary', metavar='file_name', help='Extract patterns from your an specific dictionary.')\n parser.add_argument('-o', '--output', metavar='file_name', help='Dictionary will be stored in this file.')\n parser.add_argument('-n1', type=int, default=0, help='Number of level-1 neighbours per input word (triggers LLM mode).')\n parser.add_argument('-n2', type=int, default=0, help='Optional: number of level-2 neighbours per level-1 result.')\n parser.add_argument('-n3', type=int, default=0, help='Optional: number of level-3 neighbours per level-2 result.')\n parser.add_argument('--api-key', help='LLM API key (or set LLM_API_KEY / OPENAI_API_KEY env var).')\n parser.add_argument('--base-url', help='LLM API base URL (default from config.txt or Ollama localhost).')\n parser.add_argument('--model', help='LLM model name (default from config.txt or llama3.2:3b).')\n parser.add_argument('--config', default='config.txt', help='Config file path (default: config.txt).')\n\n args = parser.parse_args()\n\n if args.light == True and args.full == True:\n print('[!] Light mode and Full mode can not be at same time. Exiting...')\n sys.exit(1)\n if args.no_verbose:\n VERBOSE = False\n if args.light:\n LIGHT_MODE = True\n verbose_print(\"[+] Light mode enabled.\")\n if args.full:\n FULL_MODE = True\n verbose_print(\"[+] Full mode enabled.\")\n verbose_print(\"[!] Warning, the output could be very heavy.\")\n if args.output:\n OUTPUT_FILE_BULEAN = True\n output_file_name = args.output\n verbose_print(\"[i] Dictionary will be stored in this file -> \"+str(output_file_name))\n\n if args.dictionary is not None:\n if is_a_valid_file(args.dictionary):\n verbose_print(\"[+] Using \"+str(args.dictionary)+\" as a dictionary.\")\n else:\n print(\"[!] File introduced as dictionary is not valid. Exiting...\")\n sys.exit(1)\n dictionary = args.dictionary\n verbose_print(\"[+] Extracting patterns... this will take a minut.\")\n BASIC_SUFIXS, BASIC_PREFIXS, NUMERIC_PATTERNS, SYMBOLIC_PATTERNS = extract_patterns(dictionary)\n verbose_print(\"[+] Patterns successfuly extracted, creating dictionary...\")\n\n if args.users is not None:\n if args.n1 > 0:\n print(\"[-] Sorry, LLM neighbour expansion is not compatible with USERS mode.\")\n sys.exit(1)\n if args.users.strip() == \"\":\n print(\"Error: This argument can not be empty\", file=sys.stderr)\n sys.exit(1)\n verbose_print(\"[+] USER mode selected.\")\n file_or_not = detec_if_file_or_not(args.users)\n if file_or_not == True:\n process_file_user(args.users, output_file_name)\n sys.exit(0)\n else:\n process_input_user(args.users, output_file_name)\n sys.exit(0)\n\n elif args.password is not None:\n if args.password.strip() == \"\":\n print(\"Error: This argument can not be empty\", file=sys.stderr)\n sys.exit(1)\n input_list = normalize_list(args.password)\n\n if args.n1 > 0:\n api_key, base_url, model = _resolve_config(args)\n verbose_print(f\"[+] LLM mode enabled. Model: {model}\")\n client = OpenAI(api_key=api_key, base_url=base_url)\n expanded = ml_expand_words(client, model, input_list, args.n1, args.n2, args.n3)\n ml_list = list(expanded)\n verbose_print(f\"[+] LLM expansion: {len(ml_list)} total words (input + neighbours).\")\n process_passwd(ml_list, output_file_name)\n sys.exit(0)\n\n verbose_print(\"[+] PASSWORD mode selected.\")\n process_passwd(input_list, output_file_name)\n sys.exit(0)\n\n if args.rules:\n all_suf = list(dict.fromkeys(BASIC_SUFIXS + NUMERIC_PATTERNS + SYMBOLIC_PATTERNS))\n all_pre = list(dict.fromkeys(BASIC_PREFIXS + NUMERIC_PATTERNS + SYMBOLIC_PATTERNS))\n verbose_print(f\"[+] Generating rules ({len(all_suf)} suffixes, {len(all_pre)} prefixes)...\")\n rules = generate_rules(all_suf, all_pre, light=args.light, full=args.full)\n verbose_print(f\"[+] {len(rules)} rules generated.\")\n if OUTPUT_FILE_BULEAN:\n save_list_to_file(rules, output_file_name)\n else:\n for rule in rules:\n print(rule)\n sys.exit(0)\n\n if args.just_neighbours is not None:\n if args.n1 <= 0:\n print(\"[-] -jn requires -n1 (at least). Use -n1 20 for example.\")\n sys.exit(1)\n\n api_key, base_url, model = _resolve_config(args)\n verbose_print(f\"[+] LLM mode enabled. Model: {model}\")\n client = OpenAI(api_key=api_key, base_url=base_url)\n\n input_list = normalize_list(args.just_neighbours)\n expanded = ml_expand_words(client, model, input_list, args.n1, args.n2, args.n3)\n result = [w for w in expanded if w not in input_list]\n if OUTPUT_FILE_BULEAN:\n save_list_to_file(result, output_file_name)\n else:\n for word in result:\n print(word)\n sys.exit(0)\n\n\nif __name__ == \"__main__\":\n main()\n\n \n \n \n"}}}}