RuleCrackPassword Cracking Rule Chain Lab

Password-cracking tools like hashcat and John the Ripper don’t only try words from a list: they can also be told to apply rules to each word — capitalize it, add a 1 at the end, swap a for @ — to guess the variations people really use. A rule is a chain of small steps run in order. Build one below, watch each step fire, and see how reordering, adding or removing a step changes the result. Positions count from 0, in bytes (é is 2 bytes). Use this only on systems you are authorized to test.

  • Hashcat syntax default Unambiguous and the de facto standard. Most published rule lists use it, and John the Ripper can run it in its hashcat-compat mode, so it's portable.
  • John's native syntax special cases Only when hashcat can't express what you need, like pluralization or John's own character classes.
Target:

01 Word to transform

02 Rule line

The same rule written as text. It updates as you edit the steps below.Paste or type a rule here to replace the steps.

03 Step chain

Steps run top to bottom, so order changes the output. Use the arrows to move a step and watch the trace change. Hover over a step to see its part of the rule line.

A reject step doesn't transform the word — it decides whether the word survives (e.g. "reject unless length ≥ 8"); once one rejects, the chain stops.
Memory steps (M 4 6 X Q) save a copy of the word and use it again later in the same rule. For example, M u 4 turns abc into ABCabc. Q rejects the word if it equals the saved copy.

04 Step-by-step trace

05 Batch test

Run the same chain against a list of words, one per line.Use a row's trace button to see how that word changes.

#InputOutput

06 Rule syntax cheat sheet

Match only the operator itself, not its example or description.

Keyboard shortcuts & accessibility

Press ? anywhere outside a text box to open this, and Esc to close it.

Keyboard

Tab Shift+Tab
Move between controls. The first Tab on the page shows skip links (to the rule line, step chain, trace, batch test and cheat sheet).
Space
On a step's checkbox: turn that step on or off. Its token in the rule line is struck through while it is off.
Alt+↑ Alt+↓
With a step's checkbox or buttons focused: move that step up or down. Focus stays on it.
Delete
With a step's checkbox or buttons focused: remove the step. Focus moves to the next one.
Ctrl+Z ⌘+Z
Undo the last deleted step (also the Undo button in the notice). Inside a text box, it undoes your typing instead.
Esc
Clear the cheat sheet search box, or close this window.

Mouse & touch

Drag
Reorder steps by dragging the dotted handle on a step's left edge. The ↑ ↓ buttons do the same without dragging.
Hover or focus
On a step, a trace row, or a token in the rule line: the matching step card, trace row and token light up together. Putting the text cursor inside a token does the same, which also works on touch screens.
Click
An example in the cheat sheet adds it to the rule line. A ↑ trace button in the batch test loads that word into section 01.
Expand
Each list is a fixed-height box so the page stays on one screen. Expand shows all of it.

Display & accessibility settings

Dark · Light · Auto
Auto follows your system's light or dark setting (dark if it doesn't say). Remembered in this browser.
A  A  A
Three text sizes; the whole page scales. Remembered.
High contrast
Pushes every text and border color to WCAG AAA (7:1 text, 4.5:1 borders), in either theme. Turns on by itself when your system asks for more contrast.
Link highlights
Turn off the hover, focus and cursor linking between steps, trace and rule line.
Scroll to match
Stop lists from scrolling to the linked item while keeping the highlights. Needs Link highlights on.
Wrap long lines
In the batch test: wrap long entries (default) or keep each on one line and scroll sideways.
Reduced motion
If your system asks to reduce motion, animations are off, scrolling is instant, and the two link switches start off (you can turn them on).

Screen readers & colour

Announcements
Moves, deletes, copies, the chain's result and the cheat sheet's match count are spoken. Every control has a name, and the toggle buttons report whether they are on.
Not colour alone
Changed characters in the trace are underlined as well as coloured. Hashcat-only operators carry an HC tag, John-only ones a J tag, and ones that need hashcat's CPU engine a CPU tag.

hashcat ↔ John native compatibility

Of the 56 operators shared between hashcat and John's own native syntax, which actually behave identically with no !! hashcat logic ON wrapper at all — not just which parse the same way.

Method

A rule counts as compatible only if the text is valid in both dialects and gives byte-identical output — checked at each operator's own boundary values (word lengths 0–8; position arguments at 0, length−1, length, length+1, length+2, and a few named positions), using this tool's hashcat and John-native engines, each independently verified against a real binary built from this project's own checkout (hashcat, john).

6
identical, including an empty word
36
identical for any ordinary word
14
diverge on ordinary words
56
shared operators checked

Fully identical — 6 operators

Same output for every word tested, including the empty string.

: noop! reject_contain% reject_contains = reject_equal_at( reject_equal_first) reject_equal_last / reject_not_contain

Identical for any real word — 36 operators

Diverge only when the word is already empty — a general caveat (see below), not operator-specific.

l lrestu urestc lrest_ufirstC urest_lfirst t trestS shift_caseT toggle_atE title e title_sepr reversed dupewordp dupeword_times f reflect{ rotate_left} rotate_rightz dupechar_first Z dupechar_lastq dupechar_ally dupeblock_firstY dupeblock_last k switch_firstK switch_last* switch_at$ append ^ prepends replace@ purgecharL chr_shiftl R chr_shiftr+ chr_incr. replace_np1, replace_nm1 M memorizeo overstrike_ reject_equal

Diverge on ordinary words — 14 operators, 5 causes

A step that empties the word: hashcat keeps it, John native rejects it

[ delete_first] delete_lastD delete_at' truncate_atO omitx extract

John's native engine rejects the candidate the moment any step empties the word (src/rules.c:1755); hashcat has no such check.

rule]word"x" hashcat"" (kept)John nativerejected
verified against real john + hashcat binaries

Length-reject boundary is off by one

< reject_less> reject_greater

hashcat's <N keeps a word when length ≤ N; John's native version only when length < N (and symmetrically for >) — so at exactly length == N, they disagree.

rule<5word"xxxxx" (len 5) hashcat"xxxxx" (kept)John nativerejected
verified against real john + hashcat binaries

Memory ops default differently before any "M"

4 append_memory6 prepend_memoryQ reject_memoryX extract_memory

hashcat rejects anything that uses the saved-word buffer before M sets it; John's native engine pre-fills it with the original word, so these work immediately.

rule4word"x" hashcatrejected (no M yet)John native"xx"
verified against real john + hashcat binaries

Insert past the end of the word

i insert

hashcat leaves the word unchanged when the insert position is out of range; John's native engine appends the character at the end instead.

rulei2aword"x" (len 1) hashcat"x" (no-op)John native"xa"
verified against real john + hashcat binaries

A letter or "8" position code after "-" reads as a reject flag

- chr_decr

John's native parser reads a leading - followed by anything but a digit — plus -8 specifically — as one of its own reject flags, not the decrement-byte command. So -A through -Z (positions 10–35) and -8 fail as a syntax error instead of decrementing that position.

rule-Aword"x" hashcat"x" (pos 10 out of range, no-op)John nativesyntax error
verified against real john binary

Scope and limits

Nothing here is a proof of compatibility — the word space either engine can receive is effectively infinite. This is boundary-focused differential testing, not exhaustive verification.

  • Operators were tested alone, not chained — a rule combining two "compatible" ones should behave the same, but that's inferred, not directly tested.
  • Character arguments used a representative set (a, Z, !, space, 0), not the full byte range — null bytes and 0xFF weren't specifically tested.
  • Boundaries were tested at word lengths up to 8, not cross-tested at large lengths too (where a separate check already found and fixed a 320-byte length bug).

Treat the 42 compatible operators as reliable for ordinary passwords and rules — not a guarantee for every conceivable input.