Welcome to lark3ri.fi

String sequence guesser with c++

27.05.2020

This program uses the full power of the CPU to compute the string given to it. You can adjust the CPU usage from the variables. It calculates the ASCII characters as numbers and it goes through every possibility until it finds the correct combination of characters, without knowing it beforehand. It just comparing against the correct one without knowing it. It only knows the length from the given correct character set because i don't want it to compute unlimitedly. You can download the code from this link.

It also has nice console loading bar while calculating and after it finds the correct string sequence, it prints the time for how long it took in nanoseconds as shown in the picture. 513041023200 is 8.55 minutes.

How long the process can be, it depends how fast your computer is where you run it and what is the length of the string that you give to this program. Longer strings take longer to go through.

It also matters where the given character is in the ASCII character set. If the character is at the end then it can significantly extend the processing time, because it needs to go through and try every wrong answer too between the beginning and the end, where the correct character is located(as we know, but the program does not know). It doesn't know the positions of the correct characters. It just calculates through everything until it finds the correct combination of characters.

ATTENTION! This program is for educational purposes only. I created it because i'm interested of how things works. About illegal aspects of this kind of programs, i don't take any responsibilities of how you use this program. I don't recommend to use it illegally and i don't take any responsibilities from that kind of actions.

passwordguesser.cpp
/*
Copyright(C) 2020 Lari Varjonen <[email protected]>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110 - 1301, USA.
*/

#include <boost/multiprecision/cpp_dec_float.hpp>
using boost::multiprecision::cpp_dec_float_50;

#include <chrono>
using namespace std::literals::chrono_literals;

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>

unsigned int max_simultaneous_threads = 16;
size_t max_single_thread_length = 4;
cpp_dec_float_50 biggest_possible_count_dec = 1;
cpp_dec_float_50 current_position_dec = 0;
std::atomic_bool process_is_running = true;
unsigned int active_threads = 0;
std::vector<int> password_found;
std::mutex lock;

void update_console(cpp_dec_float_50, cpp_dec_float_50);
void create_new_thread(std::vector<int>*, std::vector<int>*, std::vector<int>*);
void thread_work(std::vector<int>, std::vector<int>, std::vector<int>);
void add_one(std::vector<int>&, unsigned int);
bool is_equal(std::vector<int> const &v1, std::vector<int> const &v2)
{
	return (v1.size() == v2.size() &&
		std::equal(v1.begin(), v1.end(), v2.begin()));
}

int main(int argc, char* argv[])
{
	if (argc > 2)
	{
		max_simultaneous_threads = atoi(argv[1]);
		max_single_thread_length = atoi(argv[2]);
	}
	std::string user_passwd_str;
	if (argc > 3)
	{
		user_passwd_str = argv[3];
		for (int i = 4; i < argc; i++)
		{
			user_passwd_str += (char)32;
			user_passwd_str += argv[i];
		}
	}
	else
	{
		std::getline(std::cin, user_passwd_str);
	}
	if (user_passwd_str.size() <= max_single_thread_length)
	{
		max_single_thread_length = user_passwd_str.size()-1;
	}
	if (user_passwd_str.size() > max_single_thread_length)
	{
		for (unsigned int i = 0; i < user_passwd_str.size() - max_single_thread_length; i++)
		{
			biggest_possible_count_dec *= 223;
		}
	}
	std::vector<int> user_passwd;
	for (unsigned int i = 0; i < user_passwd_str.size(); i++)
	{
		int u = (int)user_passwd_str.at(i);
		if (u < 0)
		{
			u *= -1;
			u = 127 + (127 - u) + 2;
		}
		user_passwd.push_back(u);
	}

	std::vector<int> start;
	std::vector<int> end;
	std::vector<int> final_end;
	start.resize(user_passwd.size(), 32);
	end.resize(user_passwd.size(), 32);
	final_end.resize(user_passwd.size(), 255);

	std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
	while(process_is_running)
	{
		if (active_threads < max_simultaneous_threads)
		{
			create_new_thread(&user_passwd, &start, &end);
			if (is_equal(end, final_end))
			{
				while (active_threads > 0 && process_is_running);
				break;
			}
			add_one(end, 0);
			start = end;
		}
	}
	std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();

	update_console(100, 2);
	std::cout << std::endl;

	std::cout << "Password is ";
	for (unsigned int i = 0; i < password_found.size(); i++)
	{
		std::cout << (char)password_found.at(i);
	}
	std::cout << std::endl;

	auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();
	std::cout << duration << std::endl;
	
	return 0;
}

void update_console(cpp_dec_float_50 p, cpp_dec_float_50 scale)
{
	for (int i = 0; i < floor(p/scale); i++)
	{
		std::cout << (char)219;
	}
	for (int i = 0; i < 50 - floor(p/scale); i++)
	{
		std::cout << (char)176;
	}
	std::cout << (char)32 << floor(p) << "%\r";
}

void create_new_thread(std::vector<int>* user_passwd,
					   std::vector<int>* start_pos,
					   std::vector<int>* end_pos)
{
	for (unsigned int i = 0; i < max_single_thread_length; i++)
	{
		(*end_pos)[i] = 255;
	}

	current_position_dec += 1.0;
	cpp_dec_float_50 p = current_position_dec / (biggest_possible_count_dec / 100.0);
	update_console(p, 2);

	active_threads++;
	std::thread t(thread_work, *user_passwd, *start_pos, *end_pos);
	t.detach();
}

void thread_work(std::vector<int> user_passwd,
				 std::vector<int> start_pos,
				 std::vector<int> end_pos)
{
	while (process_is_running && !is_equal(start_pos, end_pos))
	{
		add_one(start_pos, 0);
		if (is_equal(start_pos, user_passwd))
		{
			std::lock_guard <std::mutex> lock(lock);
			for (unsigned int i = 0; i < start_pos.size(); i++)
			{
				password_found.push_back(start_pos.at(i));
			}
			process_is_running = false;
			break;
		}
	}
	std::lock_guard <std::mutex> lock(lock);
	active_threads--;
}

void add_one(std::vector<int> &passwd, unsigned int i)
{
	if (passwd[i] < 255)
	{
		passwd[i]++;
		if (passwd[i] == 127)
			passwd[i]++;
		return;
	}
	passwd[i] = 32;
	i++;
	if (i < passwd.size())
	{
		add_one(passwd, i);
	}
}
« Back | ↑ Top