feat: project scaffolding with CMake, configs, stubs, and core types
Includes CMakeLists.txt, CMakePresets.json, .clang-format, .clang-tidy, Config.hpp (all constants), Concepts.hpp (Hasher/AttackStrategy concepts), and stub implementations for all source files. All 6 stub tests pass.
This commit is contained in:
parent
6b347d949a
commit
4771d29342
|
|
@ -0,0 +1,14 @@
|
|||
# ©AngelaMos | 2026
|
||||
# .clang-format
|
||||
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
ColumnLimit: 100
|
||||
BreakBeforeBraces: Attach
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
IndentCaseLabels: true
|
||||
NamespaceIndentation: None
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# ©AngelaMos | 2026
|
||||
# .clang-tidy
|
||||
|
||||
Checks: >
|
||||
bugprone-*, cert-*, clang-analyzer-*, cppcoreguidelines-*, performance-*,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||
-cppcoreguidelines-pro-type-vararg,
|
||||
-cppcoreguidelines-pro-type-union-access,
|
||||
-cert-err33-c,
|
||||
-bugprone-easily-swappable-parameters
|
||||
|
||||
WarningsAsErrors: "*"
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# ©AngelaMos | 2026
|
||||
# .gitignore
|
||||
|
||||
docs/
|
||||
build/
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.out
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
compile_commands.json
|
||||
.cache/
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
.DS_Store
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# ©AngelaMos | 2026
|
||||
# CMakeLists.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.25...4.2)
|
||||
|
||||
project(
|
||||
hashcracker
|
||||
VERSION 1.0.0
|
||||
DESCRIPTION "Multi-threaded hash cracking tool"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_library(project_warnings INTERFACE)
|
||||
target_compile_options(project_warnings INTERFACE
|
||||
-Wall -Wextra -Wpedantic -Wshadow -Wconversion
|
||||
-Wnon-virtual-dtor -Wold-style-cast -Wcast-align
|
||||
-Woverloaded-virtual -Wsign-conversion
|
||||
)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS program_options)
|
||||
|
||||
set(HASHCRACKER_SOURCES
|
||||
src/hash/MD5Hasher.cpp
|
||||
src/hash/SHA1Hasher.cpp
|
||||
src/hash/SHA256Hasher.cpp
|
||||
src/hash/SHA512Hasher.cpp
|
||||
src/hash/HashDetector.cpp
|
||||
src/attack/DictionaryAttack.cpp
|
||||
src/attack/BruteForceAttack.cpp
|
||||
src/attack/RuleAttack.cpp
|
||||
src/rules/RuleSet.cpp
|
||||
src/threading/ThreadPool.cpp
|
||||
src/display/Progress.cpp
|
||||
)
|
||||
|
||||
add_library(hashcracker_lib STATIC ${HASHCRACKER_SOURCES})
|
||||
target_include_directories(hashcracker_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(hashcracker_lib
|
||||
PUBLIC OpenSSL::Crypto project_warnings
|
||||
)
|
||||
target_compile_features(hashcracker_lib PUBLIC cxx_std_23)
|
||||
|
||||
add_executable(hashcracker main.cpp)
|
||||
target_link_libraries(hashcracker
|
||||
PRIVATE hashcracker_lib Boost::program_options project_warnings
|
||||
)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG v1.15.2
|
||||
GIT_SHALLOW TRUE
|
||||
SYSTEM
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
enable_testing()
|
||||
|
||||
set(HASHCRACKER_TESTS
|
||||
tests/test_hashers.cpp
|
||||
tests/test_hash_detector.cpp
|
||||
tests/test_dictionary_attack.cpp
|
||||
tests/test_bruteforce_attack.cpp
|
||||
tests/test_rules.cpp
|
||||
tests/test_engine.cpp
|
||||
)
|
||||
|
||||
add_executable(hashcracker_tests ${HASHCRACKER_TESTS})
|
||||
target_link_libraries(hashcracker_tests
|
||||
PRIVATE hashcracker_lib GTest::gtest_main
|
||||
)
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(hashcracker_tests)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"version": 6,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "release",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{ "name": "debug", "configurePreset": "debug" },
|
||||
{ "name": "release", "configurePreset": "release" }
|
||||
],
|
||||
"testPresets": [
|
||||
{ "name": "debug", "configurePreset": "debug", "output": { "outputOnFailure": true } }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// ©AngelaMos | 2026
|
||||
// main.cpp
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// ©AngelaMos | 2026
|
||||
// BruteForceAttack.cpp
|
||||
|
||||
#include "src/attack/BruteForceAttack.hpp"
|
||||
|
||||
BruteForceAttack::BruteForceAttack(std::string_view, std::size_t,
|
||||
unsigned, unsigned) {}
|
||||
|
||||
std::expected<std::string, AttackComplete> BruteForceAttack::next() {
|
||||
return std::unexpected(AttackComplete{});
|
||||
}
|
||||
|
||||
std::size_t BruteForceAttack::total() const { return total_; }
|
||||
std::size_t BruteForceAttack::progress() const { return current_; }
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// ©AngelaMos | 2026
|
||||
// BruteForceAttack.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include "src/core/Concepts.hpp"
|
||||
|
||||
class BruteForceAttack {
|
||||
public:
|
||||
BruteForceAttack(std::string_view charset, std::size_t max_length,
|
||||
unsigned thread_index, unsigned total_threads);
|
||||
|
||||
std::expected<std::string, AttackComplete> next();
|
||||
std::size_t total() const;
|
||||
std::size_t progress() const;
|
||||
|
||||
private:
|
||||
std::size_t total_ = 0;
|
||||
std::size_t current_ = 0;
|
||||
};
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// ©AngelaMos | 2026
|
||||
// DictionaryAttack.cpp
|
||||
|
||||
#include "src/attack/DictionaryAttack.hpp"
|
||||
|
||||
std::expected<DictionaryAttack, CrackError> DictionaryAttack::create(
|
||||
std::string_view, unsigned, unsigned) {
|
||||
return std::unexpected(CrackError::FileNotFound);
|
||||
}
|
||||
|
||||
std::expected<std::string, AttackComplete> DictionaryAttack::next() {
|
||||
return std::unexpected(AttackComplete{});
|
||||
}
|
||||
|
||||
std::size_t DictionaryAttack::total() const { return 0; }
|
||||
std::size_t DictionaryAttack::progress() const { return 0; }
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// ©AngelaMos | 2026
|
||||
// DictionaryAttack.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include "src/core/Concepts.hpp"
|
||||
|
||||
class DictionaryAttack {
|
||||
public:
|
||||
static std::expected<DictionaryAttack, CrackError> create(
|
||||
std::string_view path, unsigned thread_index, unsigned total_threads);
|
||||
|
||||
std::expected<std::string, AttackComplete> next();
|
||||
std::size_t total() const;
|
||||
std::size_t progress() const;
|
||||
|
||||
private:
|
||||
DictionaryAttack() = default;
|
||||
};
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// ©AngelaMos | 2026
|
||||
// RuleAttack.cpp
|
||||
|
||||
#include "src/attack/RuleAttack.hpp"
|
||||
|
||||
std::expected<RuleAttack, CrackError> RuleAttack::create(
|
||||
std::string_view, bool, unsigned, unsigned) {
|
||||
return std::unexpected(CrackError::FileNotFound);
|
||||
}
|
||||
|
||||
std::expected<std::string, AttackComplete> RuleAttack::next() {
|
||||
return std::unexpected(AttackComplete{});
|
||||
}
|
||||
|
||||
std::size_t RuleAttack::total() const { return 0; }
|
||||
std::size_t RuleAttack::progress() const { return 0; }
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// ©AngelaMos | 2026
|
||||
// RuleAttack.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include "src/core/Concepts.hpp"
|
||||
|
||||
class RuleAttack {
|
||||
public:
|
||||
static std::expected<RuleAttack, CrackError> create(
|
||||
std::string_view path, bool chain_rules,
|
||||
unsigned thread_index, unsigned total_threads);
|
||||
|
||||
std::expected<std::string, AttackComplete> next();
|
||||
std::size_t total() const;
|
||||
std::size_t progress() const;
|
||||
|
||||
private:
|
||||
RuleAttack() = default;
|
||||
};
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
// ©AngelaMos | 2026
|
||||
// Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace config {
|
||||
|
||||
constexpr std::string_view VERSION = "1.0.0";
|
||||
constexpr std::string_view APP_NAME = "HASHCRACKER";
|
||||
|
||||
constexpr unsigned DEFAULT_THREAD_COUNT = 0;
|
||||
constexpr std::size_t DEFAULT_MAX_BRUTE_LENGTH = 6;
|
||||
constexpr int PROGRESS_UPDATE_MS = 100;
|
||||
constexpr std::size_t PROGRESS_BAR_MIN_WIDTH = 20;
|
||||
|
||||
constexpr std::string_view CHARSET_LOWER = "abcdefghijklmnopqrstuvwxyz";
|
||||
constexpr std::string_view CHARSET_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
constexpr std::string_view CHARSET_DIGITS = "0123456789";
|
||||
constexpr std::string_view CHARSET_SPECIAL = "!@#$%^&*()-_=+[]{}|;:,.<>?/~`";
|
||||
|
||||
constexpr std::size_t MD5_HEX_LENGTH = 32;
|
||||
constexpr std::size_t SHA1_HEX_LENGTH = 40;
|
||||
constexpr std::size_t SHA256_HEX_LENGTH = 64;
|
||||
constexpr std::size_t SHA512_HEX_LENGTH = 128;
|
||||
|
||||
constexpr std::size_t MAX_APPEND_DIGIT = 999;
|
||||
constexpr std::size_t MAX_PREPEND_DIGIT = 999;
|
||||
|
||||
namespace color {
|
||||
|
||||
constexpr std::string_view RESET = "\033[0m";
|
||||
constexpr std::string_view RED = "\033[31m";
|
||||
constexpr std::string_view GREEN = "\033[32m";
|
||||
constexpr std::string_view YELLOW = "\033[33m";
|
||||
constexpr std::string_view CYAN = "\033[36m";
|
||||
constexpr std::string_view BOLD = "\033[1m";
|
||||
constexpr std::string_view DIM = "\033[2m";
|
||||
|
||||
}
|
||||
|
||||
namespace box {
|
||||
|
||||
constexpr std::string_view TOP_LEFT = "\u250C";
|
||||
constexpr std::string_view TOP_RIGHT = "\u2510";
|
||||
constexpr std::string_view BOTTOM_LEFT = "\u2514";
|
||||
constexpr std::string_view BOTTOM_RIGHT = "\u2518";
|
||||
constexpr std::string_view HORIZONTAL = "\u2500";
|
||||
constexpr std::string_view VERTICAL = "\u2502";
|
||||
constexpr std::string_view BLOCK_FULL = "\u2588";
|
||||
constexpr std::string_view BLOCK_EMPTY = "\u2591";
|
||||
constexpr std::string_view BAR_LEFT = "\u2590";
|
||||
constexpr std::string_view BAR_RIGHT = "\u258C";
|
||||
|
||||
}
|
||||
|
||||
namespace icon {
|
||||
|
||||
constexpr std::string_view BOLT = "\u26A1";
|
||||
constexpr std::string_view TIMER = "\u23F1";
|
||||
constexpr std::string_view HOURGLASS = "\u23F3";
|
||||
constexpr std::string_view CHART = "\U0001F4CA";
|
||||
constexpr std::string_view CHECK = "\u2714";
|
||||
constexpr std::string_view CROSS = "\u2716";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct CrackConfig {
|
||||
std::string target_hash;
|
||||
std::string hash_type = "auto";
|
||||
std::string wordlist_path;
|
||||
std::string charset;
|
||||
std::string salt;
|
||||
std::string salt_position = "prepend";
|
||||
std::string output_path;
|
||||
std::size_t max_length = config::DEFAULT_MAX_BRUTE_LENGTH;
|
||||
unsigned thread_count = config::DEFAULT_THREAD_COUNT;
|
||||
bool bruteforce = false;
|
||||
bool use_rules = false;
|
||||
bool chain_rules = false;
|
||||
};
|
||||
|
||||
struct CrackResult {
|
||||
std::string plaintext;
|
||||
std::string hash;
|
||||
std::string algorithm;
|
||||
double elapsed_seconds;
|
||||
std::size_t candidates_tested;
|
||||
double hashes_per_second;
|
||||
};
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// ©AngelaMos | 2026
|
||||
// Concepts.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
struct AttackComplete {};
|
||||
|
||||
enum class CrackError {
|
||||
FileNotFound,
|
||||
InvalidHash,
|
||||
UnsupportedAlgorithm,
|
||||
OpenSSLError,
|
||||
InvalidConfig,
|
||||
Exhausted
|
||||
};
|
||||
|
||||
constexpr std::string_view crack_error_message(CrackError e) {
|
||||
switch (e) {
|
||||
case CrackError::FileNotFound: return "File not found";
|
||||
case CrackError::InvalidHash: return "Invalid hash format";
|
||||
case CrackError::UnsupportedAlgorithm: return "Unsupported hash algorithm";
|
||||
case CrackError::OpenSSLError: return "OpenSSL internal error";
|
||||
case CrackError::InvalidConfig: return "Invalid configuration";
|
||||
case CrackError::Exhausted: return "All candidates exhausted";
|
||||
}
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
concept Hasher = requires(T h, std::string_view input) {
|
||||
{ h.hash(input) } -> std::same_as<std::string>;
|
||||
{ T::name() } -> std::convertible_to<std::string_view>;
|
||||
{ T::digest_length() } -> std::same_as<std::size_t>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept AttackStrategy = requires(T a) {
|
||||
{ a.next() } -> std::same_as<std::expected<std::string, AttackComplete>>;
|
||||
{ a.total() } -> std::same_as<std::size_t>;
|
||||
{ a.progress() } -> std::same_as<std::size_t>;
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// ©AngelaMos | 2026
|
||||
// Progress.cpp
|
||||
|
||||
#include "src/display/Progress.hpp"
|
||||
#include "src/config/Config.hpp"
|
||||
|
||||
Progress::Progress(std::string_view algorithm, std::string_view attack_mode,
|
||||
unsigned thread_count, std::size_t total_candidates,
|
||||
const std::atomic<bool>& found,
|
||||
const std::atomic<std::size_t>& tested)
|
||||
: algorithm_(algorithm), attack_mode_(attack_mode),
|
||||
thread_count_(thread_count), total_(total_candidates),
|
||||
found_(found), tested_(tested) {}
|
||||
|
||||
void Progress::print_banner() const {}
|
||||
void Progress::update() {}
|
||||
void Progress::print_cracked(const CrackResult&) const {}
|
||||
void Progress::print_exhausted(std::string_view, std::string_view) const {}
|
||||
bool Progress::is_tty() { return false; }
|
||||
std::size_t Progress::terminal_width() { return 80; }
|
||||
std::string Progress::render_bar(double, std::size_t) const { return ""; }
|
||||
std::string Progress::format_count(std::size_t) { return ""; }
|
||||
std::string Progress::format_time(double) { return ""; }
|
||||
std::string Progress::format_speed(double) { return ""; }
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// ©AngelaMos | 2026
|
||||
// Progress.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
struct CrackResult;
|
||||
|
||||
class Progress {
|
||||
public:
|
||||
Progress(std::string_view algorithm, std::string_view attack_mode,
|
||||
unsigned thread_count, std::size_t total_candidates,
|
||||
const std::atomic<bool>& found,
|
||||
const std::atomic<std::size_t>& tested);
|
||||
|
||||
void print_banner() const;
|
||||
void update();
|
||||
void print_cracked(const CrackResult& result) const;
|
||||
void print_exhausted(std::string_view hash, std::string_view algorithm) const;
|
||||
static bool is_tty();
|
||||
|
||||
private:
|
||||
std::string algorithm_;
|
||||
std::string attack_mode_;
|
||||
unsigned thread_count_;
|
||||
std::size_t total_;
|
||||
const std::atomic<bool>& found_;
|
||||
const std::atomic<std::size_t>& tested_;
|
||||
|
||||
static std::size_t terminal_width();
|
||||
std::string render_bar(double fraction, std::size_t width) const;
|
||||
static std::string format_count(std::size_t n);
|
||||
static std::string format_time(double seconds);
|
||||
static std::string format_speed(double hps);
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// HashDetector.cpp
|
||||
|
||||
#include "src/hash/HashDetector.hpp"
|
||||
|
||||
std::expected<HashType, CrackError> HashDetector::detect(std::string_view) {
|
||||
return std::unexpected(CrackError::InvalidHash);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// ©AngelaMos | 2026
|
||||
// HashDetector.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
#include "src/core/Concepts.hpp"
|
||||
|
||||
enum class HashType { MD5, SHA1, SHA256, SHA512 };
|
||||
|
||||
class HashDetector {
|
||||
public:
|
||||
static std::expected<HashType, CrackError> detect(std::string_view hash);
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// MD5Hasher.cpp
|
||||
|
||||
#include "src/hash/MD5Hasher.hpp"
|
||||
|
||||
std::string MD5Hasher::hash(std::string_view) const {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// ©AngelaMos | 2026
|
||||
// MD5Hasher.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class MD5Hasher {
|
||||
public:
|
||||
std::string hash(std::string_view input) const;
|
||||
static constexpr std::string_view name() { return "MD5"; }
|
||||
static constexpr std::size_t digest_length() { return 32; }
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// SHA1Hasher.cpp
|
||||
|
||||
#include "src/hash/SHA1Hasher.hpp"
|
||||
|
||||
std::string SHA1Hasher::hash(std::string_view) const {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// ©AngelaMos | 2026
|
||||
// SHA1Hasher.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class SHA1Hasher {
|
||||
public:
|
||||
std::string hash(std::string_view input) const;
|
||||
static constexpr std::string_view name() { return "SHA1"; }
|
||||
static constexpr std::size_t digest_length() { return 40; }
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// SHA256Hasher.cpp
|
||||
|
||||
#include "src/hash/SHA256Hasher.hpp"
|
||||
|
||||
std::string SHA256Hasher::hash(std::string_view) const {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// ©AngelaMos | 2026
|
||||
// SHA256Hasher.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class SHA256Hasher {
|
||||
public:
|
||||
std::string hash(std::string_view input) const;
|
||||
static constexpr std::string_view name() { return "SHA256"; }
|
||||
static constexpr std::size_t digest_length() { return 64; }
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// SHA512Hasher.cpp
|
||||
|
||||
#include "src/hash/SHA512Hasher.hpp"
|
||||
|
||||
std::string SHA512Hasher::hash(std::string_view) const {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// ©AngelaMos | 2026
|
||||
// SHA512Hasher.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class SHA512Hasher {
|
||||
public:
|
||||
std::string hash(std::string_view input) const;
|
||||
static constexpr std::string_view name() { return "SHA512"; }
|
||||
static constexpr std::size_t digest_length() { return 128; }
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// ©AngelaMos | 2026
|
||||
// RuleSet.cpp
|
||||
|
||||
#include "src/rules/RuleSet.hpp"
|
||||
|
||||
std::generator<std::string> RuleSet::capitalize_first(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::uppercase_all(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::leet_speak(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::append_digits(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::prepend_digits(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::reverse(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::toggle_case(std::string_view) { co_return; }
|
||||
std::generator<std::string> RuleSet::apply_all(std::string_view) { co_return; }
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// ©AngelaMos | 2026
|
||||
// RuleSet.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <generator>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class RuleSet {
|
||||
public:
|
||||
static std::generator<std::string> capitalize_first(std::string_view word);
|
||||
static std::generator<std::string> uppercase_all(std::string_view word);
|
||||
static std::generator<std::string> leet_speak(std::string_view word);
|
||||
static std::generator<std::string> append_digits(std::string_view word);
|
||||
static std::generator<std::string> prepend_digits(std::string_view word);
|
||||
static std::generator<std::string> reverse(std::string_view word);
|
||||
static std::generator<std::string> toggle_case(std::string_view word);
|
||||
static std::generator<std::string> apply_all(std::string_view word);
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// ©AngelaMos | 2026
|
||||
// ThreadPool.cpp
|
||||
|
||||
#include "src/threading/ThreadPool.hpp"
|
||||
|
||||
void SharedState::set_result(std::string plaintext) {
|
||||
found.store(true, std::memory_order_relaxed);
|
||||
auto lock = std::lock_guard{result_mutex};
|
||||
if (!result.has_value()) {
|
||||
result = std::move(plaintext);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPool::ThreadPool(unsigned thread_count)
|
||||
: thread_count_(thread_count > 0 ? thread_count
|
||||
: std::thread::hardware_concurrency()) {}
|
||||
|
||||
void ThreadPool::run(WorkFn) {}
|
||||
|
||||
SharedState& ThreadPool::state() { return state_; }
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// ©AngelaMos | 2026
|
||||
// ThreadPool.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
struct SharedState {
|
||||
std::atomic<bool> found{false};
|
||||
std::atomic<std::size_t> tested_count{0};
|
||||
std::mutex result_mutex;
|
||||
std::optional<std::string> result;
|
||||
|
||||
void set_result(std::string plaintext);
|
||||
};
|
||||
|
||||
class ThreadPool {
|
||||
public:
|
||||
using WorkFn = std::function<void(unsigned thread_id, unsigned total, SharedState&)>;
|
||||
|
||||
explicit ThreadPool(unsigned thread_count);
|
||||
|
||||
void run(WorkFn work);
|
||||
SharedState& state();
|
||||
|
||||
private:
|
||||
unsigned thread_count_;
|
||||
SharedState state_;
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// test_bruteforce_attack.cpp
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(BruteForceAttackTest, Stub) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// test_dictionary_attack.cpp
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(DictionaryAttackTest, Stub) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// test_engine.cpp
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(EngineTest, Stub) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// test_hash_detector.cpp
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(HashDetectorTest, Stub) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// ©AngelaMos | 2026
|
||||
// test_hashers.cpp
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "src/hash/SHA256Hasher.hpp"
|
||||
|
||||
TEST(SHA256HasherTest, Stub) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// ©AngelaMos | 2026
|
||||
// test_rules.cpp
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(RuleSetTest, Stub) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
Loading…
Reference in New Issue