Commit 9c6b74f1 authored by Mathieu Valois's avatar Mathieu Valois
Browse files

Implements OpenMP multi-threading. Implements #3.

parents df80fdf5 6b13e0ab
Loading
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
# Version de cmake demandée.
cmake_minimum_required(VERSION 2.8)

find_package(Threads REQUIRED)
find_package(OpenMP)

# Chemin des répertoires contenant les fichiers entêtes.
include_directories(include)
@@ -10,8 +10,7 @@ include_directories(include)
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})

# Option du compilateur pour supporter C 2011.
set(CMAKE_CXX_FLAGS "-pedantic -Wall -std=c++11 -Wextra -O3")
set(CMAKE_LD_FLAGS "-lpthread")
set(CMAKE_CXX_FLAGS "-pedantic -Wall -std=c++11 -Wextra -O3 -fopenmp")

add_executable(cppack
				src/core/Statsgen.cpp
+3 −10
Original line number Diff line number Diff line
@@ -26,21 +26,14 @@ class ProgressThread : public QThread
{
    Q_OBJECT
    void run() {
        unsigned int progress = 0;
        uint64_t processed = 0;
        const std::vector<ThreadData>& td = _s.getThreadsData();

        int progress = 0;
        while(!_s.allStarted()){
            msleep(500);
        }
        const uint64_t nblines = td.back().lineEnd;
        const uint64_t nblines = _s.getNbLines();

        while(!_s.allFinished()){
            processed = 0;
            for(ThreadData t : td){
                processed += t.total_counter;
            }
            progress = (int) percentage(processed, nblines);
            progress = (int) percentage(_s.getProcessed(), nblines);
            _qpb.setValue(progress);
            msleep(500);
        }
+17 −96
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@

#include <string>
#include <iostream>
#include <thread>

#include "Policy.h"
#include "SecurityRules.h"
@@ -39,123 +38,38 @@ public:
	Statsgen(){}
	Statsgen(const std::string& name);

	/**
	 * @brief useful to hide statistics below 1%
	 * @param hr: 1 to hide, else 0
	 */
	inline void setHiderare(const int& hr) { hiderare = hr; }
	int generate_stats();
	void print_stats() const;

	/**
	 * @brief Defining the number of best results the user wants to see,
	 * and so the result should be clearer
	 * @param t: number of interesting results
	 */
	inline void setHiderare(const int& hr) { hiderare = hr; }
	inline void setTop(const int& t) { top = t; }

	/**
	 * @brief Defining a regular expression to analyse only
	 * some interesting passwords
	 * @param reg: regular expression
	 */
	inline void setRegex(const std::string& reg) {
		current_regex = reg;
		use_regex = true;
	}

	/**
	 * @brief Useful to know if the database uses the format withcount
	 * @param var: true if database uses the format withcount, else false
	 */
	inline void setWithcount(const bool& wc) { withcount = wc; }

	/**
	 * @brief Filter for the size of the simple masks, can be
	 * used as an optimisation option
	 * @param limit: number that limit the size of the simple masks
	 */
	inline void setLimitSimplemask(const int& limit) { limitSimplemask = limit; }

	/**
	 * @brief Filter for the size of the advanced masks, can be
	 * used as an optimisation option
	 * @param limit: number that limit the size of the advanced masks
	 */
	inline void setLimitAdvancedmask(const int& limit) { limitAdvancedmask = limit; }

	/**
	 * @brief Number of threads the user wants to use
	 * @param nb: number of usable threads
	 */
	inline void setNbThread(const int& nb) {
		int max = std::thread::hardware_concurrency();
		if (nb > max) {
			nbThread = max;
		} else {
			nbThread = nb;
		}
	}

	inline void setNbThread(const int& nb) { nbThread = nb; }
	void configureThread(ThreadData& td) const;


	/**
	 * @brief Defining all security rules
	 */
	void askSecurityRules();
	void setSecurityRules(const uint& length, const uint& special, const uint& digit, const uint& upper, const uint& lower);

	/**
	 * @brief Where to write masks
	 * @param outfile: the file where to write masks
	 */
	inline void setOutfile(const std::string& outfile) { outfile_name = outfile; }

	/**
	 * @brief enable debugging
	 */
	inline void enableDebug() { debug_enabled = true; }


	/**
	 * @brief Calculate all statistics for a database
	 * @return 0 if error, 1 if success
	 */
	int generate_stats();


	/**
	 * @brief Print all calculated statistics
	 */
	void print_stats();

	inline uint64_t getTotalCounter() const { return td[0].total_counter; }
	inline uint64_t getTotalFilter() const { return td[0].total_filter; }
	inline uint64_t getNbSecurePasswords() const { return td[0].sr.nbSecurePassword; }
	inline int getNbThreads() const { return nbThread; }
	inline const IntOccurrence& getStatsLength() const { return td[0].length; }
	inline const StringOccurrence& getStatsCharsets() const { return td[0].charactersets; }
	inline const StringOccurrence& getStatsSimple() const { return td[0].simplemasks; }
	inline const StringOccurrence& getStatsAdvanced() const { return td[0].advancedmasks; }
	inline const std::vector<ThreadData>& getThreadsData() const { return td; }
	inline bool allFinished() const { return finished == nbThread; }
	inline uint64_t getNbLines() const { return nblines; }
	inline uint64_t getProcessed() const { return processed; }
	inline const ThreadData& getResults() const { return results; }
	inline bool allFinished() const { return finished; }
	inline bool allStarted() const { return started; }
	bool operator==(const Statsgen& other) const;

	/**
	* @brief Given parameters in threadarg, compute statistics on partition of the file
	* @param threadarg : parameters and result storage
	*/
	static void* generate_stats_thread(void * threadarg);

private:
	std::string filename;
	// results of the computation
	ThreadData results;
	// Data computed from within a thread, for read-accessibility
	std::vector<ThreadData> td;

	// Filters

	int hiderare = 0; 				// Hide low statistics
	int top = 10;					// Show only a top of statistics
	std::regex current_regex;		// Regex for the interesting passwords
@@ -170,10 +84,17 @@ private:
	// Security policy
	SecurityRules _sr = { 0, 8, 0, 1, 1, 1	};

	// threads which have finished
	uint finished = 0;
	// nb lines processed
	uint64_t nblines = 0;
	// nb lines processed
	uint64_t processed = 0;
	// all threads have finished
	uint finished = false;
	// all threads have been started
	bool started = false;

	void handle_password(const std::string& password, const uint64_t& nbPasswords, ThreadData& td) const;
	std::pair<uint, uint> get_masks(const std::string& password, PasswordStats& c) const;
};

#endif
+3 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
typedef std::unordered_map<std::string, uint64_t> StringOccurrence;
typedef std::unordered_map<int, uint64_t> IntOccurrence;


/**
 * @brief minimal number of digits of a password, etc.
 */
@@ -61,4 +62,6 @@ struct ThreadData {
	SecurityRules sr;
};

#pragma omp declare reduction(dataSum: ThreadData : omp_out += omp_in ) initializer(omp_priv(omp_orig))

#endif // THREAD_DATA_H
 No newline at end of file
+4 −3
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ using MapIterator = typename std::map<K, V>::const_iterator;
 * @return ordered map
 */
template<typename A>
std::map<uint64_t, A, std::greater<uint64_t>> flip_map(const std::unordered_map<A, uint64_t> & src) {
	std::map<uint64_t, A, std::greater<uint64_t>> dst;
std::multimap<uint64_t, A, std::greater<uint64_t>> flip_map(const std::unordered_map<A, uint64_t> & src) {
	std::multimap<uint64_t, A, std::greater<uint64_t>> dst;

	for(UnorderedMapIterator<A, uint64_t> it = src.begin(); it != src.end(); ++it)
		dst.insert(std::make_pair(it->second, it->first));
@@ -56,6 +56,7 @@ std::map<uint64_t, A, std::greater<uint64_t>> flip_map(const std::unordered_map<
 */
template<typename Type>
void readResult(const uint64_t & res, const Type& carac, int & count, const uint64_t & total_counter, const int & hiderare) {
	if(res == 0) return;
	std::ostringstream ss;
	float perc = percentage(res, total_counter);

@@ -83,7 +84,7 @@ void readResult(const uint64_t & res, const Type& carac, int & count, const uint
template<typename Type>
void showMap(const std::unordered_map<Type, uint64_t> & stats, const int & top, const uint64_t & total_counter, const int & hiderare, int & count) {
	count = 0;
	std::map<uint64_t, Type, std::greater<uint64_t>> reverse = flip_map<Type>(stats);
	std::multimap<uint64_t, Type, std::greater<uint64_t>> reverse = flip_map<Type>(stats);
	std::pair<uint64_t, Type> it;
	for(std::pair<uint64_t, Type> it : reverse) {
		readResult<Type>(it.first, it.second, count, total_counter, hiderare);
Loading