Skip to content

Commit

Permalink
Add Combinator external mode (combines words into pairs)
Browse files Browse the repository at this point in the history
  • Loading branch information
solardiz committed May 18, 2024
1 parent 97a023b commit 133232a
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ Major changes from 1.9.0-jumbo-1 (May 2019) in this bleeding-edge version:

- Add Armory wallet support (accepts btcrecover data extracts). [Solar; 2024]

- Add Combinator external mode (combines words into pairs). [Solar; 2024]


Major changes from 1.8.0-jumbo-1 (December 2014) to 1.9.0-jumbo-1 (May 2019):

Expand Down
89 changes: 89 additions & 0 deletions run/john.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3880,6 +3880,95 @@ void filter()
status = 1; // Print the status line
}

# Several hybrid external modes follow. These are to be used on top of another
# cracking mode and they generate multiple candidate passwords from each "word"
# output by the other mode.

# Combine words coming from another cracking mode into pairs. This gradually
# memorizes up to the initial 1 MB worth of words and uses them to prefix and
# suffix each current word.
# Known limitations:
# 1. --restore of interrupted session does not work right (no opportunity to
# re-memorize the other mode's skipped words), so do not use it.
# 2. The progress indicator and ETA are too optimistic (they assume linear
# progress through the input stream, but complexity within 1 MB is quadratic).
# Example usage: --wordlist --external=combinator --rules-stack=phrase
[List.External:Combinator]
int separator;
int words[1000000], size;
int base[63], base_size, base_length, swap, p, q;

void init()
{
separator = ' '; // Set to 0 for no separators

size = 1000000; // Must not exceed size of words array
base_size = 63; // Must not exceed size of base array, nor (125-1)/2+1

if (req_maxlen && base_size > req_maxlen + 1)
base_size = req_maxlen + 1;
q = 0;
}

void new()
{
swap = p = 0;

/* Memorize this base word if it fits and is of right length */
base_length = -1;
while (q < size && (words[q++] = word[++base_length]))
continue;
if (q < size && base_length < base_size && base_length)
return;

/* Don't memorize this base word, but finish computing its length */
q -= base_length + 1;
while (word[++base_length])
continue;
}

void next()
{
int i, j;

if (base_length >= base_size) {
word = 0;
return;
}

if (swap) {
/* Next memorized word first, separator and current base word next */
i = -1;
while (word[++i] = words[p++])
continue;
if (p >= q) {
word = 0;
return;
}
if (separator)
word[i++] = separator;
j = 0;
while (word[i++] = base[j++])
continue;
return;
}

/* Current base word first, separator and next memorized word next */
i = base_length;
if (separator)
word[i++] = separator;
while (word[i++] = words[p++])
continue;
if (p >= q) {
p = 0;
swap++;
i = -1;
while (++i < base_length)
base[i] = word[i];
base[i] = 0;
}
}

#
# Reference example hybrid-mode external. same as jtr-rule: $[0-9]$[0-9]
# this format is to be used similar to a filter, in that it requires some
Expand Down

0 comments on commit 133232a

Please sign in to comment.