0

So I need to crack a hash to solve a puzzle, and I've edited a Python program that iterates over all possible combinations, but the Python program is too slow as the hash changes every day, I know it's a hash of length: 8

The python program would work like this:

charset = "abcdefghijklmnopqrstuvwxyz012345679"
NUMBER_OF_CHARACTERS = len(charset)
sequence = list("a a a a a a a a".split(" "))
while(True):
    current = "".join(sequence)
    sequence = next(sequence)
    #check if hash of sequence matches target hash

the function: 'next' looks like this:

if len(string) <= 0:
    string.append(indexToCharacter(0))
else:
    string[0] = indexToCharacter((characterToIndex(string[0]) + 1) % NUMBER_OF_CHARACTERS)
    if characterToIndex(string[0]) is 0:
        return list(string[0]) + next(string[1:])
return string

indexToCharacter just returns the character in string charset at index (index)
characterToIndex returns the position of a given character in string index

so, characterToIndex("a") would return 0 and indexToCharacter(0) would return "a"

Now what I need is, to convert this Python program to a C++ program, as C++ is way faster, I have the indexToCharacter function, the characterToIndex function, but I can't seem to get the next function work.

I got this for the next function in C++

string next(string sequence)
{
    sequence[0] = indexToCharacter(characterToIndex(sequence[0])+1);
    if (characterToIndex(sequence[0]) == 0)
    {
        //Something
    }
}

string sequence = "aaaaaaaa";
next(sequence);

the code of indexToCharacter and characterToIndex:

int characterToIndex(char character)
{
    return charset.find(character);
}

char indexToCharacter(unsigned index)
{
    return charset[index];
}
TheXReflex
  • 55
  • 1
  • 12
  • So you just need to implement the next() function in c++? – Wajahat Jul 15 '16 at 16:49
  • Yes, only need the next function in c++ – TheXReflex Jul 15 '16 at 16:51
  • Atleast provide what is the expected output to an input for the `next` function. – Arunmu Jul 15 '16 at 16:52
  • So... Just write whatever the Python version does in C++ and use `string(1,sequence[0])` instead of `list(string[0])`. The problem is, such calls to `string` will allocate tons of memory in various places, so your memory will get very fragmented – ForceBru Jul 15 '16 at 16:52
  • Also please provide the entire code, implementation of indexToCharacter etc. – Wajahat Jul 15 '16 at 16:53
  • @Arunmu expected output for "aaaaaaaa" would be "baaaaaaa" – TheXReflex Jul 15 '16 at 16:53
  • Have you tried using Cython? You can keep your code in python, but compile it down for faster performance. It may save everyone time. – Taztingo Jul 15 '16 at 16:54
  • What's more, appending data to lists (and `std::string`s) is quite expensive in terms of time and memory. The same is applied to various `find` methods. – ForceBru Jul 15 '16 at 16:54
  • @Taztingo I'll try that out, might be most interesting thing to do – TheXReflex Jul 15 '16 at 16:56
  • You may consider this route: profile your current python code to find which are your actual bottle=neck. You could use the cProfile Module, or Robert Kern’s line_profiler. Once you know which lines/stanzas of your code need to be converted to C++, use cython to convert just these sections. You may also explore Shed Skin, Pythran, and PyPy, as they may give you the needed speed boost you need without actually doing much work. – boardrider Jul 17 '16 at 14:47
  • Also see [Convert Python program to C/C++ code?](https://stackoverflow.com/q/4650243/608639) – jww Nov 21 '19 at 13:36

1 Answers1

1

In this special case, I would not hassle around with the std::string objects all the time. You have a fixed length, right? You can do it very efficiently this way then (works both in C++ and C... – just adjust buffer length and characters list to your own needs):

char characters[] = { 'a', 'b', 'c' };
char buffer[3];
char* positions[sizeof(buffer)];
for(unsigned int i = 0; i < sizeof(buffer); ++i)
{
    buffer[i] = *characters;
    positions[i] = characters;
}

unsigned int i;
do
{
    printf("%.*s\n", (int)sizeof(buffer), buffer);
    for(i = 0; i < sizeof(buffer); ++i)
    {
        ++positions[i];
        if(positions[i] < characters + sizeof(characters))
        {
            buffer[i] = *positions[i];
            break;
        }
        positions[i] = characters;
    }
}
while(i < sizeof(buffer));

I just printed out the values, you can do what ever you need to do with...

Aconcagua
  • 24,880
  • 4
  • 34
  • 59