diff --git a/PROJECTS/beginner/hash-cracker/.clang-format b/PROJECTS/beginner/hash-cracker/.clang-format new file mode 100644 index 00000000..b7d2b1ef --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/.clang-format @@ -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 diff --git a/PROJECTS/beginner/hash-cracker/.clang-tidy b/PROJECTS/beginner/hash-cracker/.clang-tidy new file mode 100644 index 00000000..e35c41ec --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/.clang-tidy @@ -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: "*" diff --git a/PROJECTS/beginner/hash-cracker/.gitignore b/PROJECTS/beginner/hash-cracker/.gitignore new file mode 100644 index 00000000..d9379b90 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/.gitignore @@ -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 diff --git a/PROJECTS/beginner/hash-cracker/CMakeLists.txt b/PROJECTS/beginner/hash-cracker/CMakeLists.txt new file mode 100644 index 00000000..3ae70bba --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/CMakeLists.txt @@ -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) diff --git a/PROJECTS/beginner/hash-cracker/CMakePresets.json b/PROJECTS/beginner/hash-cracker/CMakePresets.json new file mode 100644 index 00000000..72b0de33 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/CMakePresets.json @@ -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 } } + ] +} diff --git a/PROJECTS/beginner/hash-cracker/main.cpp b/PROJECTS/beginner/hash-cracker/main.cpp new file mode 100644 index 00000000..e696711c --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/main.cpp @@ -0,0 +1,6 @@ +// ©AngelaMos | 2026 +// main.cpp + +int main() { + return 0; +} diff --git a/PROJECTS/beginner/hash-cracker/src/attack/BruteForceAttack.cpp b/PROJECTS/beginner/hash-cracker/src/attack/BruteForceAttack.cpp new file mode 100644 index 00000000..836a532b --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/attack/BruteForceAttack.cpp @@ -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 BruteForceAttack::next() { + return std::unexpected(AttackComplete{}); +} + +std::size_t BruteForceAttack::total() const { return total_; } +std::size_t BruteForceAttack::progress() const { return current_; } diff --git a/PROJECTS/beginner/hash-cracker/src/attack/BruteForceAttack.hpp b/PROJECTS/beginner/hash-cracker/src/attack/BruteForceAttack.hpp new file mode 100644 index 00000000..9919b010 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/attack/BruteForceAttack.hpp @@ -0,0 +1,24 @@ +// ©AngelaMos | 2026 +// BruteForceAttack.hpp + +#pragma once + +#include +#include +#include +#include +#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 next(); + std::size_t total() const; + std::size_t progress() const; + +private: + std::size_t total_ = 0; + std::size_t current_ = 0; +}; diff --git a/PROJECTS/beginner/hash-cracker/src/attack/DictionaryAttack.cpp b/PROJECTS/beginner/hash-cracker/src/attack/DictionaryAttack.cpp new file mode 100644 index 00000000..6cea48ca --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/attack/DictionaryAttack.cpp @@ -0,0 +1,16 @@ +// ©AngelaMos | 2026 +// DictionaryAttack.cpp + +#include "src/attack/DictionaryAttack.hpp" + +std::expected DictionaryAttack::create( + std::string_view, unsigned, unsigned) { + return std::unexpected(CrackError::FileNotFound); +} + +std::expected DictionaryAttack::next() { + return std::unexpected(AttackComplete{}); +} + +std::size_t DictionaryAttack::total() const { return 0; } +std::size_t DictionaryAttack::progress() const { return 0; } diff --git a/PROJECTS/beginner/hash-cracker/src/attack/DictionaryAttack.hpp b/PROJECTS/beginner/hash-cracker/src/attack/DictionaryAttack.hpp new file mode 100644 index 00000000..b0c6573d --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/attack/DictionaryAttack.hpp @@ -0,0 +1,23 @@ +// ©AngelaMos | 2026 +// DictionaryAttack.hpp + +#pragma once + +#include +#include +#include +#include +#include "src/core/Concepts.hpp" + +class DictionaryAttack { +public: + static std::expected create( + std::string_view path, unsigned thread_index, unsigned total_threads); + + std::expected next(); + std::size_t total() const; + std::size_t progress() const; + +private: + DictionaryAttack() = default; +}; diff --git a/PROJECTS/beginner/hash-cracker/src/attack/RuleAttack.cpp b/PROJECTS/beginner/hash-cracker/src/attack/RuleAttack.cpp new file mode 100644 index 00000000..9055de89 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/attack/RuleAttack.cpp @@ -0,0 +1,16 @@ +// ©AngelaMos | 2026 +// RuleAttack.cpp + +#include "src/attack/RuleAttack.hpp" + +std::expected RuleAttack::create( + std::string_view, bool, unsigned, unsigned) { + return std::unexpected(CrackError::FileNotFound); +} + +std::expected RuleAttack::next() { + return std::unexpected(AttackComplete{}); +} + +std::size_t RuleAttack::total() const { return 0; } +std::size_t RuleAttack::progress() const { return 0; } diff --git a/PROJECTS/beginner/hash-cracker/src/attack/RuleAttack.hpp b/PROJECTS/beginner/hash-cracker/src/attack/RuleAttack.hpp new file mode 100644 index 00000000..7718495b --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/attack/RuleAttack.hpp @@ -0,0 +1,24 @@ +// ©AngelaMos | 2026 +// RuleAttack.hpp + +#pragma once + +#include +#include +#include +#include +#include "src/core/Concepts.hpp" + +class RuleAttack { +public: + static std::expected create( + std::string_view path, bool chain_rules, + unsigned thread_index, unsigned total_threads); + + std::expected next(); + std::size_t total() const; + std::size_t progress() const; + +private: + RuleAttack() = default; +}; diff --git a/PROJECTS/beginner/hash-cracker/src/config/Config.hpp b/PROJECTS/beginner/hash-cracker/src/config/Config.hpp new file mode 100644 index 00000000..cec56b6a --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/config/Config.hpp @@ -0,0 +1,96 @@ +// ©AngelaMos | 2026 +// Config.hpp + +#pragma once + +#include +#include +#include +#include + +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; +}; diff --git a/PROJECTS/beginner/hash-cracker/src/core/Concepts.hpp b/PROJECTS/beginner/hash-cracker/src/core/Concepts.hpp new file mode 100644 index 00000000..7394dab3 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/core/Concepts.hpp @@ -0,0 +1,47 @@ +// ©AngelaMos | 2026 +// Concepts.hpp + +#pragma once + +#include +#include +#include +#include +#include + +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 +concept Hasher = requires(T h, std::string_view input) { + { h.hash(input) } -> std::same_as; + { T::name() } -> std::convertible_to; + { T::digest_length() } -> std::same_as; +}; + +template +concept AttackStrategy = requires(T a) { + { a.next() } -> std::same_as>; + { a.total() } -> std::same_as; + { a.progress() } -> std::same_as; +}; diff --git a/PROJECTS/beginner/hash-cracker/src/display/Progress.cpp b/PROJECTS/beginner/hash-cracker/src/display/Progress.cpp new file mode 100644 index 00000000..4f8849f9 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/display/Progress.cpp @@ -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& found, + const std::atomic& 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 ""; } diff --git a/PROJECTS/beginner/hash-cracker/src/display/Progress.hpp b/PROJECTS/beginner/hash-cracker/src/display/Progress.hpp new file mode 100644 index 00000000..45a135bb --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/display/Progress.hpp @@ -0,0 +1,39 @@ +// ©AngelaMos | 2026 +// Progress.hpp + +#pragma once + +#include +#include +#include +#include + +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& found, + const std::atomic& 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& found_; + const std::atomic& 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); +}; diff --git a/PROJECTS/beginner/hash-cracker/src/hash/HashDetector.cpp b/PROJECTS/beginner/hash-cracker/src/hash/HashDetector.cpp new file mode 100644 index 00000000..27662655 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/HashDetector.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// HashDetector.cpp + +#include "src/hash/HashDetector.hpp" + +std::expected HashDetector::detect(std::string_view) { + return std::unexpected(CrackError::InvalidHash); +} diff --git a/PROJECTS/beginner/hash-cracker/src/hash/HashDetector.hpp b/PROJECTS/beginner/hash-cracker/src/hash/HashDetector.hpp new file mode 100644 index 00000000..0949b63e --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/HashDetector.hpp @@ -0,0 +1,15 @@ +// ©AngelaMos | 2026 +// HashDetector.hpp + +#pragma once + +#include +#include +#include "src/core/Concepts.hpp" + +enum class HashType { MD5, SHA1, SHA256, SHA512 }; + +class HashDetector { +public: + static std::expected detect(std::string_view hash); +}; diff --git a/PROJECTS/beginner/hash-cracker/src/hash/MD5Hasher.cpp b/PROJECTS/beginner/hash-cracker/src/hash/MD5Hasher.cpp new file mode 100644 index 00000000..707bc822 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/MD5Hasher.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// MD5Hasher.cpp + +#include "src/hash/MD5Hasher.hpp" + +std::string MD5Hasher::hash(std::string_view) const { + return ""; +} diff --git a/PROJECTS/beginner/hash-cracker/src/hash/MD5Hasher.hpp b/PROJECTS/beginner/hash-cracker/src/hash/MD5Hasher.hpp new file mode 100644 index 00000000..fadb3827 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/MD5Hasher.hpp @@ -0,0 +1,15 @@ +// ©AngelaMos | 2026 +// MD5Hasher.hpp + +#pragma once + +#include +#include +#include + +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; } +}; diff --git a/PROJECTS/beginner/hash-cracker/src/hash/SHA1Hasher.cpp b/PROJECTS/beginner/hash-cracker/src/hash/SHA1Hasher.cpp new file mode 100644 index 00000000..c37e2e03 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/SHA1Hasher.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// SHA1Hasher.cpp + +#include "src/hash/SHA1Hasher.hpp" + +std::string SHA1Hasher::hash(std::string_view) const { + return ""; +} diff --git a/PROJECTS/beginner/hash-cracker/src/hash/SHA1Hasher.hpp b/PROJECTS/beginner/hash-cracker/src/hash/SHA1Hasher.hpp new file mode 100644 index 00000000..bd5f2942 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/SHA1Hasher.hpp @@ -0,0 +1,15 @@ +// ©AngelaMos | 2026 +// SHA1Hasher.hpp + +#pragma once + +#include +#include +#include + +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; } +}; diff --git a/PROJECTS/beginner/hash-cracker/src/hash/SHA256Hasher.cpp b/PROJECTS/beginner/hash-cracker/src/hash/SHA256Hasher.cpp new file mode 100644 index 00000000..798c80b2 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/SHA256Hasher.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// SHA256Hasher.cpp + +#include "src/hash/SHA256Hasher.hpp" + +std::string SHA256Hasher::hash(std::string_view) const { + return ""; +} diff --git a/PROJECTS/beginner/hash-cracker/src/hash/SHA256Hasher.hpp b/PROJECTS/beginner/hash-cracker/src/hash/SHA256Hasher.hpp new file mode 100644 index 00000000..a65780a6 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/SHA256Hasher.hpp @@ -0,0 +1,15 @@ +// ©AngelaMos | 2026 +// SHA256Hasher.hpp + +#pragma once + +#include +#include +#include + +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; } +}; diff --git a/PROJECTS/beginner/hash-cracker/src/hash/SHA512Hasher.cpp b/PROJECTS/beginner/hash-cracker/src/hash/SHA512Hasher.cpp new file mode 100644 index 00000000..cc45c0f6 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/SHA512Hasher.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// SHA512Hasher.cpp + +#include "src/hash/SHA512Hasher.hpp" + +std::string SHA512Hasher::hash(std::string_view) const { + return ""; +} diff --git a/PROJECTS/beginner/hash-cracker/src/hash/SHA512Hasher.hpp b/PROJECTS/beginner/hash-cracker/src/hash/SHA512Hasher.hpp new file mode 100644 index 00000000..ec68a570 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/hash/SHA512Hasher.hpp @@ -0,0 +1,15 @@ +// ©AngelaMos | 2026 +// SHA512Hasher.hpp + +#pragma once + +#include +#include +#include + +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; } +}; diff --git a/PROJECTS/beginner/hash-cracker/src/rules/RuleSet.cpp b/PROJECTS/beginner/hash-cracker/src/rules/RuleSet.cpp new file mode 100644 index 00000000..24be5881 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/rules/RuleSet.cpp @@ -0,0 +1,13 @@ +// ©AngelaMos | 2026 +// RuleSet.cpp + +#include "src/rules/RuleSet.hpp" + +std::generator RuleSet::capitalize_first(std::string_view) { co_return; } +std::generator RuleSet::uppercase_all(std::string_view) { co_return; } +std::generator RuleSet::leet_speak(std::string_view) { co_return; } +std::generator RuleSet::append_digits(std::string_view) { co_return; } +std::generator RuleSet::prepend_digits(std::string_view) { co_return; } +std::generator RuleSet::reverse(std::string_view) { co_return; } +std::generator RuleSet::toggle_case(std::string_view) { co_return; } +std::generator RuleSet::apply_all(std::string_view) { co_return; } diff --git a/PROJECTS/beginner/hash-cracker/src/rules/RuleSet.hpp b/PROJECTS/beginner/hash-cracker/src/rules/RuleSet.hpp new file mode 100644 index 00000000..b5b8563e --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/rules/RuleSet.hpp @@ -0,0 +1,20 @@ +// ©AngelaMos | 2026 +// RuleSet.hpp + +#pragma once + +#include +#include +#include + +class RuleSet { +public: + static std::generator capitalize_first(std::string_view word); + static std::generator uppercase_all(std::string_view word); + static std::generator leet_speak(std::string_view word); + static std::generator append_digits(std::string_view word); + static std::generator prepend_digits(std::string_view word); + static std::generator reverse(std::string_view word); + static std::generator toggle_case(std::string_view word); + static std::generator apply_all(std::string_view word); +}; diff --git a/PROJECTS/beginner/hash-cracker/src/threading/ThreadPool.cpp b/PROJECTS/beginner/hash-cracker/src/threading/ThreadPool.cpp new file mode 100644 index 00000000..cc993029 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/threading/ThreadPool.cpp @@ -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_; } diff --git a/PROJECTS/beginner/hash-cracker/src/threading/ThreadPool.hpp b/PROJECTS/beginner/hash-cracker/src/threading/ThreadPool.hpp new file mode 100644 index 00000000..51eeec0c --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/src/threading/ThreadPool.hpp @@ -0,0 +1,35 @@ +// ©AngelaMos | 2026 +// ThreadPool.hpp + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +struct SharedState { + std::atomic found{false}; + std::atomic tested_count{0}; + std::mutex result_mutex; + std::optional result; + + void set_result(std::string plaintext); +}; + +class ThreadPool { +public: + using WorkFn = std::function; + + explicit ThreadPool(unsigned thread_count); + + void run(WorkFn work); + SharedState& state(); + +private: + unsigned thread_count_; + SharedState state_; +}; diff --git a/PROJECTS/beginner/hash-cracker/tests/test_bruteforce_attack.cpp b/PROJECTS/beginner/hash-cracker/tests/test_bruteforce_attack.cpp new file mode 100644 index 00000000..5c85810a --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/tests/test_bruteforce_attack.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// test_bruteforce_attack.cpp + +#include + +TEST(BruteForceAttackTest, Stub) { + EXPECT_TRUE(true); +} diff --git a/PROJECTS/beginner/hash-cracker/tests/test_dictionary_attack.cpp b/PROJECTS/beginner/hash-cracker/tests/test_dictionary_attack.cpp new file mode 100644 index 00000000..50df97f4 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/tests/test_dictionary_attack.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// test_dictionary_attack.cpp + +#include + +TEST(DictionaryAttackTest, Stub) { + EXPECT_TRUE(true); +} diff --git a/PROJECTS/beginner/hash-cracker/tests/test_engine.cpp b/PROJECTS/beginner/hash-cracker/tests/test_engine.cpp new file mode 100644 index 00000000..e140f7c6 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/tests/test_engine.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// test_engine.cpp + +#include + +TEST(EngineTest, Stub) { + EXPECT_TRUE(true); +} diff --git a/PROJECTS/beginner/hash-cracker/tests/test_hash_detector.cpp b/PROJECTS/beginner/hash-cracker/tests/test_hash_detector.cpp new file mode 100644 index 00000000..5c802182 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/tests/test_hash_detector.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// test_hash_detector.cpp + +#include + +TEST(HashDetectorTest, Stub) { + EXPECT_TRUE(true); +} diff --git a/PROJECTS/beginner/hash-cracker/tests/test_hashers.cpp b/PROJECTS/beginner/hash-cracker/tests/test_hashers.cpp new file mode 100644 index 00000000..af3d5965 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/tests/test_hashers.cpp @@ -0,0 +1,9 @@ +// ©AngelaMos | 2026 +// test_hashers.cpp + +#include +#include "src/hash/SHA256Hasher.hpp" + +TEST(SHA256HasherTest, Stub) { + EXPECT_TRUE(true); +} diff --git a/PROJECTS/beginner/hash-cracker/tests/test_rules.cpp b/PROJECTS/beginner/hash-cracker/tests/test_rules.cpp new file mode 100644 index 00000000..14cd8fe3 --- /dev/null +++ b/PROJECTS/beginner/hash-cracker/tests/test_rules.cpp @@ -0,0 +1,8 @@ +// ©AngelaMos | 2026 +// test_rules.cpp + +#include + +TEST(RuleSetTest, Stub) { + EXPECT_TRUE(true); +}