README
The
REFCODES.ORG
codes represent a group of artifacts consolidating parts of my work in the past years. Several topics are covered which I consider useful for you, programmers, developers and software engineers.
What is this repository for?
This artifact provides word morphs mass production functionality for generating arbitrary distinct IDs similar to UUIDs (as of the UniqueIdGenerator
type) or for generating permutations of words with a given alphabet and permutation rules (as of the AlphabetCounter
alongside the AlphabetCounterComposite
types) as well as multi threading concurrency support (as of the ConcurrentBufferedGeneratorDecorator
and ThreadLocalBufferedGeneratorDecorator
types) for such Generator
(Iterator
) types.
Please keep in mind that the permutation functionality introduced below is intended for personal data recovery and educational use only! Please respect the privacy of your fellow people!
How do I get set up?
To get up and running, include the following dependency (without the three dots “…”) in your pom.xml
:
1
2
3
4
5
6
7
8
9
<dependencies>
...
<dependency>
<artifactId>refcodes-generator</artifactId>
<groupId>org.refcodes</groupId>
<version>3.3.9</version>
</dependency>
...
</dependencies>
The artifact is hosted directly at Maven Central. Jump straight to the source codes at Bitbucket. Read the artifact’s javadoc at javadoc.io.
Snippets of interest
Below find some code snippets which demonstrate the various aspects of using the refcodes-generator
artifact (and , if applicable, its offsprings). See also the example source codes of this artifact for further information on the usage of this artifact.
Tailor-made password permutations
Tailor-made password permutations use expressions to define permutations aspects and chaining of multiple such defined permutations together to produce custom password ranges.
The code snippet below will produce all permutations ranging from Secret
till secret999password???
:
1
2
3
4
5
6
7
8
9
10
11
12
import org.refcodes.generator.AlphabetCounterComposite;
...
AlphabetCounterComposite theCounter = new AlphabetCounterComposite(
"('Secret','secret')", // 1st part of the password
"[0-3]:{0-9}", // 2nd part of the password
"('','Password','password')", // 3rd part of the password
"[0-3]:{!,?}" // 4th part of the password
);
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
...
Note that the daisy chained expressions ('Secret','secret')
, [0-3]:{0-9}
, ('','Password','password')
, and "[0-3]:{!,?}
combined are responsible for the last secret999password???
password’s portions secret
, 999
, password
and ???
(in that order) and produce 99990 password variants!
The code snippet below will produce all permutations ranging from A000
till ZZZ999
(this may take a while):
1
2
3
4
5
6
7
8
9
10
import org.refcodes.generator.AlphabetCounterComposite;
...
AlphabetCounterComposite theCounter = new AlphabetCounterComposite(
"[1-3]:{A-Z}", // 1st part of the password
"[3-3]:{0-9}" // 2nd part of the password
);
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
...
Note that the daisy chained expressions [1-3]:{A-Z}
and [3-3]:{0-9}
combined are responsible for the last ZZZ999
password’s portions ZZZ
and 999
(in that order) and produce 18278000 password variants!
Daisy chaining multiple expressions enables you to create arbitrary complex custom password counters.
Producing permutations from character sets
The code snippet below will produce all permutations with lengths between 2
and 4
for the letters a
, b
, c
, d
, e
, f
ranging from aa
till ffff
:
1
2
3
4
5
6
7
8
9
import org.refcodes.generator.AlphabetCounter;
...
AlphabetCounter theCounter = new AlphabetCounter( 2, 4, 'a', 'b', 'c', 'd', 'e', 'f' );
System.out.println( theCounter.toAlphabetExpression() );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
System.out.println( theCounter.toAlphabetExpression() );
...
Note that the below output’s first [2-4]:{a,b,c,d,e,f}:"aa"
and last [2-4]:{a,b,c,d,e,f}:"ffff"
lines are not part of the counter’s permutations though represent expressions defining the counter’s initial and final state!
The code snippet below will produce all permutations with lengths between 2
and 4
for all hexadecimal digits ranging from 00
till FFFF
(as of the CharSet
definition):
1
2
3
4
5
6
7
8
9
import org.refcodes.generator.AlphabetCounter;
...
AlphabetCounter theCounter = new AlphabetCounter( 2, 4, CharSet.HEXADECIMAL );
System.out.println( theCounter.toAlphabetExpression() );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
System.out.println( theCounter.toAlphabetExpression() );
...
Note that the below output’s first [2-4]:{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}:"00"
and last [2-4]:{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}:"FFFF"
lines are not part of the counter’s permutations though represent expressions defining the counter’s initial and final state!
Counting through word lists
The code snippet below will produce all the elements this
, is
, my
, word
, list
, to
, iterate
, through
:
1
2
3
4
5
6
7
8
9
10
11
import org.refcodes.generator.AlphabetCounter;
...
AlphabetCounter theCounter = new AlphabetCounter(
new String[] { "this", "is", "my", "word", "list", "to", "iterate", "through" }
);
System.out.println( theCounter.toAlphabetExpression() );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
System.out.println( theCounter.toAlphabetExpression() );
...
Note that the below output’s first ("this","is","my","word","list","to","iterate","through"):"this"
and last ("this","is","my","word","list","to","iterate","through"):"through"
lines are not part of the counter’s permutations though represent expressions defining the counter’s initial and final state!
Producing permutations from expressions
Using the expression [2-4]:{a,b,c,d,e,f}:'ce'
the code snippet below will produce all permutations with lengths between 2
and 4
for the letters a
, b
, c
, d
, e
, f
ranging from ce
till ffff
:
Please keep in mind that expressions are like a shy fairies: Spaces not useful in definition are rejected with disapproval!
1
2
3
4
5
6
7
8
9
import org.refcodes.generator.AlphabetCounter;
...
AlphabetCounter theCounter = new AlphabetCounter( "[2-4]:{a,b,c,d,e,f}:'ce'" );
System.out.println( theCounter.toAlphabetExpression() );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
System.out.println( theCounter.toAlphabetExpression() );
...
Note that the below output’s first [2-4]:{a,b,c,d,e,f}:"ce"
and last [2-4]:{a,b,c,d,e,f}:"ffff"
lines are not part of the counter’s permutations though represent expressions defining the counter’s initial and final state!
Calling
reset()
on the above counter will make it start fromaa
again; This is important when daisy chaining counters behind each other to produce the full set of permutations of all counters combined and still be able to resume from a given counter’s state (seeAlphabetCounterDecorator
class).
Using the expression [2-4]:{HEXADECIMAL}:'CE'
the code snippet below will produce all permutations with lengths between 2
and 4
for all hexadecimal digits ranging from CE
till FFFF
(as of the CharSet
definition):
1
2
3
4
5
6
7
8
9
import org.refcodes.generator.AlphabetCounter;
...
AlphabetCounter theCounter = new AlphabetCounter( "[2-4]:{HEXADECIMAL}:'CE'" );
System.out.println( theCounter.toAlphabetExpression() );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
System.out.println( theCounter.toAlphabetExpression() );
...
Note that the below output’s first [2-4]:{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}:"CE""
and last [2-4]:{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}:"FFFF"
lines are not part of the counter’s permutations though represent expressions defining the counter’s initial and final state!
Calling
reset()
on the above counter will make it start from00
again; This is important when daisy chaining counters behind each other to produce the full set of permutations of all counters combined and still be able to resume from a given counter’s state (seeAlphabetCounterComposite
class).
Daisy chaining counters to produce complex passwords
The code snippet below will produce all permutations ranging from A000
till ZZZ999
(this may take a while):
1
2
3
4
5
6
7
8
9
10
import org.refcodes.generator.AlphabetCounterComposite;
...
AlphabetCounterComposite theCounter = new AlphabetCounterComposite(
"[1-3]:{A-Z}", // 1st part of the password
"[3-3]:{0-9}" // 2nd part of the password
);
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
...
Note that the daisy chained expressions [1-3]:{A-Z}
and [3-3]:{0-9}
are responsible for the first A000
password’s portions A
and 000
(in that order) and combined produce 18278000 password variants!
Alternate ways of declaring such a counter are as follows, producing the same result as the example above:
1
2
3
4
5
6
7
8
9
import org.refcodes.generator.AlphabetCounterComposite;
...
AlphabetCounter theCounter1 = new AlphabetCounter( "[1-3]:{A-Z}" );
AlphabetCounter theCounter2 = new AlphabetCounter( "[3-3]:{0-9}" );
AlphabetCounterComposite theCounter = new AlphabetCounterComposite( theCounter1, theCounter2 );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
...
Note that the above code snippet still uses expressions [1-3]:{A-Z}
as well as [3-3]:{0-9}
to define the counters!
1
2
3
4
5
6
7
8
9
import org.refcodes.generator.AlphabetCounterComposite;
...
AlphabetCounter theCounter1 = new AlphabetCounter( 1, 3, CharSet.UPPER_CASE );
AlphabetCounter theCounter2 = new AlphabetCounter( 3, 3, CharSet.DECIMAL );
AlphabetCounterComposite theCounter = new AlphabetCounterComposite( theCounter1, theCounter2 );
while ( theCounter.hasNext() ) {
System.out.println( theCounter.next() );
}
...
Note that the above code snippet defines the counters programmatically without the need to declare expressions!
Generating arbitrary distinct IDs
The code snippet below produces 1000 distinct IDs (you may produce as many as fast as you want):
1
2
3
4
5
6
import org.refcodes.generator.UniqueIdGeneratorSingleton;
...
for ( int i = 0; i < 1000; i++ ) {
System.out.println( UniqueIdGeneratorSingleton.getInstance().next() );
}
...
Note that a singleton is used with a predefined length of 36 with the IDs being BASE-64 URL alike encoded (padding chars are omitted)!
The code snippet below also produces 1000 distinct IDs (you may produce as many as fast as you want):
1
2
3
4
5
6
7
import org.refcodes.generator.UniqueIdGenerator;
...
UniqueIdGenerator theGenerator = new UniqueIdGenerator( 16 );
for ( int i = 0; i < 1000; i++ ) {
System.out.println( theGenerator.next() );
}
...
Note that a length of 16 is used with the IDs being BASE-64 URL alike encoded (padding chars are omitted)!
Multi threading concurrency and buffered generators
The code snippet below uses a ConcurrentBufferedGeneratorDecorator
to encapsulate a Generator
instance for concurrent (multi threaded) access with a minimum of blocking as of synchronization issues (e.g. the AlphabetCounter
and the AlphabetCounterComposite
avoid synchronization as far as possible causing issues with the internal state when directly been accessed from multiple threads).
1
2
3
4
5
6
7
8
9
10
11
import org.refcodes.generator.AlphabetCounterComposite;
import org.refcodes.generator.ConcurrentBufferedGeneratorDecorator;
...
AlphabetCounterComposite theCounter = new AlphabetCounterComposite( "'HelloWorld'", "[0-32]:{0-9,A-Z,a-z}" );
BufferedGenerator<String> theGenerator = new ConcurrentBufferedGeneratorDecorator<>( theCounter );
int index = 0;
while ( theGenerator.hasNext() && index < 1000 ) {
System.out.println( theGenerator.next() );
index++;
}
...
Note that the ConcurrentBufferedGeneratorDecorator
internally uses a separate thread to fill up a BlockingQueue
which makes it safe to be used in a multi threaded environment though does not completely eliminates delays as of synchronization issues!
You may also use
Iterator
instances with theConcurrentBufferedGeneratorDecorator
type!
The code snippet below uses a ThreadLocalBufferedGeneratorDecorator
to encapsulate a Generator
instance for concurrent (multi threaded) access with a minimum of blocking as of synchronization issues (e.g. the AlphabetCounter
and the AlphabetCounterComposite
avoid synchronization as far as possible causing issues with the internal state when directly been accessed from multiple threads).
1
2
3
4
5
6
7
8
9
10
11
import org.refcodes.generator.AlphabetCounterComposite;
import org.refcodes.generator.ThreadLocalBufferedGeneratorDecorator;
...
AlphabetCounterComposite theCounter = new AlphabetCounterComposite( "'HelloWorld'", "[0-32]:{0-9,A-Z,a-z}" );
BufferedGenerator<String> theGenerator = new ThreadLocalBufferedGeneratorDecorator<>( theCounter );
int index = 0;
while ( theGenerator.hasNext() && index < 1000 ) {
System.out.println( theGenerator.next() );
index++;
}
...
Note that the CRACKZIP application seems to benefit much more from the ThreadLocalBufferedGeneratorDecorator
as from the ConcurrentBufferedGeneratorDecorator
even though it does not use a separate thread though instead uses ThreadLocal
buffers filled up by the according threads themselves.
You may also use
Iterator
instances with theThreadLocalBufferedGeneratorDecorator
type!
Examples
See the CRACKZIP applications’ source code, the PASSGEN applications’ source code as well as the example source codes of this artifact for further information on the usage of this artifact.
Contribution guidelines
- Report issues
- Finding bugs
- Helping fixing bugs
- Making code and documentation better
- Enhance the code
Who do I talk to?
- Siegfried Steiner (steiner@refcodes.org)
Terms and conditions
The REFCODES.ORG
group of artifacts is published under some open source licenses; covered by the refcodes-licensing
(org.refcodes
group) artifact - evident in each artifact in question as of the pom.xml
dependency included in such artifact.