This is just straight bruteforce with the ability to select multiple charset for one word, being able to mash up the linearity with a modulo. This code is also posted on GitHub.
Generateur.h
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
class Generateur
{
private:
bool two, three;
int length1, length2, length3, min, max, loop, size3;
char *first, *middle, *last, *tmp, *ptr;
long counter2, counter3, *array;
void exiterr(char *msg);
void gen(long index0);
public:
Generateur(int argc, char *argv[]);
~Generateur();
};
zhou.cpp
#include "Generateur.h"
int main(int argc, char *argv[])
{
Generateur gen(argc, argv);
}
Generateur.cpp
#include "Generateur.h"
Generateur::Generateur(int argc, char *argv[])
{
if (argc < 4) { printf("./zhou min max [first] middle [last [length]].\n");exit(-1); }
if(!(min = atoi(argv[1]))) { printf("./zhou min max [first] middle [last [length]].\n");exit(-1); }
if(!(max = atoi(argv[2]))) { printf("./zhou min max [first] middle [last [length]].\n");exit(-1); }
long index0;//this one runs
two = three = false;
index0 = loop = 0; //index is the core variable with the array, loop is needed in case max > min
counter2 = counter3 = 0;
size3 = 1; //when not used we need it anyway because we are substracting it to the password's length for looping
array = new long[max];
tmp = new char[max];
first = new char[strlen(argv[3])];
strcpy(first, argv[3]);
length1 = strlen(first);
if(argc > 4)//is there a second charset ?
{
two = true;
middle = new char[strlen(argv[4])];
strcpy(middle, argv[4]);
length2 = strlen(middle);
}
if(argc > 5)//a third ?
{
if(argc < 7) { printf("Needs expand of last character set\n"); exit(-1); }
three = true;
last = new char[strlen(argv[5])];
strcpy(last, argv[5]);
length3 = strlen(last);
size3 = atoi(argv[6]);
}
for(int i=0; i<max; i++)
{
array[i] = 0;
}
gen(index0);//Entry
}
Generateur::~Generateur()
{
delete(tmp);
delete(first);
if(two)
delete(middle);
if(three)
delete(last);
}
void Generateur::gen(long index0)
{
if(index0 == 0)
{
for(loop=0; loop<max-min+1; loop++)
for(array[index0]=0; array[index0]<length1; array[index0]++)
if(index0 < min+loop-1) gen(index0+1);
}
else
{
for(array[index0]=0; array[index0]<length1; array[index0]++)
{
if(index0 < min+loop-1 && !two) gen(index0+1);
else
{
ptr = &tmp[0];
for(int a=0; a < min+loop; a++)
{
snprintf(ptr, 2, "%c", first[(array[a]+counter3)%length1]);
ptr++;
}
if(two)
{
for(array[index0]; array[index0]<length2; array[index0]++)
{
if(index0 < min+loop-size3) gen(index0+1);
else
{
ptr = &tmp[1];
for(int a=0; a < min+loop-size3; a++)
{
snprintf(ptr, 2, "%c", middle[(array[a+1]+counter2)%length2]);
ptr++;
}
if(three)
{
for(array[index0]; array[index0]<length3; array[index0]++)
{
if(index0 < min+loop-1) gen(index0+1);
else
{
ptr = &tmp[min+loop-size3];
for(int a=0; a<size3; a++)
{
snprintf(ptr, 2, "%c", last[(array[min+loop-size3+a])%length3]);
ptr++;
}
printf("%s\n", tmp);
counter3++;
}
}
}
else
printf("%s\n", tmp);
counter2++;
}
}
}
else
printf("%s\n", tmp);
}
}
}
}