From 973d984c557671d54fcb6f085295c2306053fccb Mon Sep 17 00:00:00 2001 From: zsyg <3872006562@qq.com> Date: Mon, 7 Jul 2025 20:37:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=9F=E5=BC=83=E7=9A=84=E9=9B=B6=E5=AE=BD?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=9A=90=E8=97=8F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 欸 --- others/C++/stegano_project/Makefile | 32 +++++++ .../stegano_project/include/CommonDefs.hpp | 19 ++++ others/C++/stegano_project/include/GUI.hpp | 36 ++++++++ .../stegano_project/include/Steganography.hpp | 16 ++++ .../include/ZeroWidthEncoder.hpp | 17 ++++ .../stegano_project/src/CommonDefsImpl.cpp | 16 ++++ others/C++/stegano_project/src/GUI.cpp | 92 +++++++++++++++++++ .../C++/stegano_project/src/Steganography.cpp | 25 +++++ .../stegano_project/src/ZeroWidthEncoder.cpp | 41 +++++++++ others/C++/stegano_project/src/main.cpp | 13 +++ 10 files changed, 307 insertions(+) create mode 100644 others/C++/stegano_project/Makefile create mode 100644 others/C++/stegano_project/include/CommonDefs.hpp create mode 100644 others/C++/stegano_project/include/GUI.hpp create mode 100644 others/C++/stegano_project/include/Steganography.hpp create mode 100644 others/C++/stegano_project/include/ZeroWidthEncoder.hpp create mode 100644 others/C++/stegano_project/src/CommonDefsImpl.cpp create mode 100644 others/C++/stegano_project/src/GUI.cpp create mode 100644 others/C++/stegano_project/src/Steganography.cpp create mode 100644 others/C++/stegano_project/src/ZeroWidthEncoder.cpp create mode 100644 others/C++/stegano_project/src/main.cpp diff --git a/others/C++/stegano_project/Makefile b/others/C++/stegano_project/Makefile new file mode 100644 index 0000000..dc69149 --- /dev/null +++ b/others/C++/stegano_project/Makefile @@ -0,0 +1,32 @@ +# Makefile for Zero-Width Steganography tool + +CXX = g++ +CXXFLAGS = -Iinclude -Wall -Wextra -std=c++11 -static +LDFLAGS = -static -lfltk -lfltk_images -lole32 -luuid -lcomctl32 -lgdi32 -lws2_32 -ldwmapi -lwinspool + +SRC_DIR = src +SRCS = $(SRC_DIR)/main.cpp \ + $(SRC_DIR)/GUI.cpp \ + $(SRC_DIR)/Steganography.cpp \ + $(SRC_DIR)/ZeroWidthEncoder.cpp \ + $(SRC_DIR)/CommonDefsImpl.cpp +OBJS = $(SRCS:.cpp=.o) +EXEC = zwsteg.exe + +# FLTK路径设置 +FLTK_INCLUDE = "C:/msys64/ucrt64/include" +FLTK_LIB = "C:/msys64/ucrt64/lib" + +all: $(EXEC) + +$(EXEC): $(OBJS) + $(CXX) $(CXXFLAGS) -o $@ $^ -L$(FLTK_LIB) $(LDFLAGS) \ + -ljpeg -lpng -lz -lgdiplus -lgdi32 -limm32 + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -I$(FLTK_INCLUDE) -c $< -o $@ + +clean: + rm -f $(OBJS) $(EXEC) + +.PHONY: all clean \ No newline at end of file diff --git a/others/C++/stegano_project/include/CommonDefs.hpp b/others/C++/stegano_project/include/CommonDefs.hpp new file mode 100644 index 0000000..89ddbf4 --- /dev/null +++ b/others/C++/stegano_project/include/CommonDefs.hpp @@ -0,0 +1,19 @@ +#ifndef COMMON_DEFS_HPP +#define COMMON_DEFS_HPP + +#include +#include +#include + +namespace CommonDefs { + // 零宽字符定义 + constexpr wchar_t ZERO_WIDTH_SPACE = 0x200B; // 用于表示二进制0 + constexpr wchar_t ZERO_WIDTH_NON_JOINER = 0x200C; // 用于表示二进制1 + constexpr wchar_t ZERO_WIDTH_JOINER = 0x200D; // 用于分隔符 + + // 转换函数声明 + std::wstring utf8_to_wstring(const std::string& str); + std::string wstring_to_utf8(const std::wstring& wstr); +} + +#endif // COMMON_DEFS_HPP \ No newline at end of file diff --git a/others/C++/stegano_project/include/GUI.hpp b/others/C++/stegano_project/include/GUI.hpp new file mode 100644 index 0000000..ca2f823 --- /dev/null +++ b/others/C++/stegano_project/include/GUI.hpp @@ -0,0 +1,36 @@ +// include/GUI.hpp (添加类前向声明) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Steganography.hpp" + +class MainWindow : public Fl_Window { +public: + MainWindow(int width, int height, const char* title); + +private: + Fl_Tabs* tabs; + Fl_Group* embedGroup; + Fl_Group* extractGroup; + + // Embed widgets + Fl_Multiline_Input* coverInput; + Fl_Multiline_Input* messageInput; + Fl_Button* encodeBtn; + Fl_Multiline_Output* resultOutput; + + // Extract widgets + Fl_Multiline_Input* extractInput; + Fl_Button* decodeBtn; + Fl_Multiline_Output* extractedOutput; + + // Callbacks + static void encode_cb(Fl_Widget* w, void* data); + static void decode_cb(Fl_Widget* w, void* data); +}; \ No newline at end of file diff --git a/others/C++/stegano_project/include/Steganography.hpp b/others/C++/stegano_project/include/Steganography.hpp new file mode 100644 index 0000000..727c706 --- /dev/null +++ b/others/C++/stegano_project/include/Steganography.hpp @@ -0,0 +1,16 @@ +#ifndef STEGANOGRAPHY_HPP +#define STEGANOGRAPHY_HPP + +#include "ZeroWidthEncoder.hpp" +#include + +class Steganography { +public: + static std::wstring embed(const std::wstring& cover_text, const std::string& message); + static std::string extract(const std::wstring& stego_text); + +private: + static bool is_zero_width(wchar_t c); +}; + +#endif // STEGANOGRAPHY_HPP \ No newline at end of file diff --git a/others/C++/stegano_project/include/ZeroWidthEncoder.hpp b/others/C++/stegano_project/include/ZeroWidthEncoder.hpp new file mode 100644 index 0000000..fb32b21 --- /dev/null +++ b/others/C++/stegano_project/include/ZeroWidthEncoder.hpp @@ -0,0 +1,17 @@ +#ifndef ZERO_WIDTH_ENCODER_HPP +#define ZERO_WIDTH_ENCODER_HPP + +#include "CommonDefs.hpp" +#include + +class ZeroWidthEncoder { +public: + static std::wstring encode(const std::string& message); + static std::string decode(const std::wstring& encoded); + +private: + static std::wstring char_to_zero_width(char c); + static char zero_width_to_char(const std::wstring& sequence); +}; + +#endif // ZERO_WIDTH_ENCODER_HPP \ No newline at end of file diff --git a/others/C++/stegano_project/src/CommonDefsImpl.cpp b/others/C++/stegano_project/src/CommonDefsImpl.cpp new file mode 100644 index 0000000..1c152ba --- /dev/null +++ b/others/C++/stegano_project/src/CommonDefsImpl.cpp @@ -0,0 +1,16 @@ +#include "CommonDefs.hpp" +#include +#include +#include + +namespace CommonDefs { + std::wstring utf8_to_wstring(const std::string& str) { + std::wstring_convert> converter; + return converter.from_bytes(str); + } + + std::string wstring_to_utf8(const std::wstring& wstr) { + std::wstring_convert> converter; + return converter.to_bytes(wstr); + } +} \ No newline at end of file diff --git a/others/C++/stegano_project/src/GUI.cpp b/others/C++/stegano_project/src/GUI.cpp new file mode 100644 index 0000000..109f2ed --- /dev/null +++ b/others/C++/stegano_project/src/GUI.cpp @@ -0,0 +1,92 @@ +// src/GUI.cpp (改进布局) +#include "GUI.hpp" +#include "Steganography.hpp" +#include "CommonDefs.hpp" +#include +#include + +const int PAD = 15; +const int WIDTH = 600; +const int HEIGHT = 600; +const int BTN_WIDTH = 120; +const int BTN_HEIGHT = 30; + +MainWindow::MainWindow(int width, int height, const char* title) + : Fl_Window(width, height, title) { + + begin(); + + // 创建标签页 + tabs = new Fl_Tabs(0, 0, WIDTH, HEIGHT); + tabs->selection_color(FL_BLUE); + + // 嵌入标签页 + embedGroup = new Fl_Group(0, 30, WIDTH, HEIGHT - 30, "Embed"); + embedGroup->color(FL_WHITE); + embedGroup->selection_color(FL_WHITE); + + int y = PAD + 30; + + coverInput = new Fl_Multiline_Input(PAD, y, WIDTH - 2 * PAD, 80, "Cover Text:"); + coverInput->align(FL_ALIGN_TOP_LEFT); + y += 90; + + messageInput = new Fl_Multiline_Input(PAD, y, WIDTH - 2 * PAD, 80, "Secret Message:"); + messageInput->align(FL_ALIGN_TOP_LEFT); + y += 90; + + encodeBtn = new Fl_Button(WIDTH - BTN_WIDTH - PAD, y, BTN_WIDTH, BTN_HEIGHT, "Embed"); + encodeBtn->callback(encode_cb, this); + encodeBtn->color(FL_GREEN); + y += 40; + + resultOutput = new Fl_Multiline_Output(PAD, y, WIDTH - 2 * PAD, 80, "Result (with hidden text):"); + resultOutput->align(FL_ALIGN_TOP_LEFT); + resultOutput->textsize(12); + resultOutput->readonly(1); + y += 90; + + // 状态标签 + Fl_Box* statusBox = new Fl_Box(PAD, y, WIDTH - 2 * PAD, 30, ""); + statusBox->label("Status: Ready"); + + embedGroup->end(); + + // 提取标签页 + extractGroup = new Fl_Group(0, 30, WIDTH, HEIGHT - 30, "Extract"); + extractGroup->color(FL_WHITE); + extractGroup->selection_color(FL_WHITE); + + y = PAD + 30; + + extractInput = new Fl_Multiline_Input(PAD, y, WIDTH - 2 * PAD, 80, "Text to decode:"); + extractInput->align(FL_ALIGN_TOP_LEFT); + y += 90; + + decodeBtn = new Fl_Button(WIDTH - BTN_WIDTH - PAD, y, BTN_WIDTH, BTN_HEIGHT, "Extract"); + decodeBtn->callback(decode_cb, this); + decodeBtn->color(FL_BLUE); + y += 40; + + extractedOutput = new Fl_Multiline_Output(PAD, y, WIDTH - 2 * PAD, 80, "Extracted Message:"); + extractedOutput->align(FL_ALIGN_TOP_LEFT); + extractedOutput->textsize(12); + extractedOutput->readonly(1); + y += 90; + + // 状态标签 + Fl_Box* extractStatus = new Fl_Box(PAD, y, WIDTH - 2 * PAD, 30, ""); + extractStatus->label("Status: Ready"); + + extractGroup->end(); + tabs->end(); + + end(); + + // 设置默认选择的标签 + tabs->value(embedGroup); + + // 窗口美化 + color(FL_WHITE); + resizable(this); +} diff --git a/others/C++/stegano_project/src/Steganography.cpp b/others/C++/stegano_project/src/Steganography.cpp new file mode 100644 index 0000000..8163380 --- /dev/null +++ b/others/C++/stegano_project/src/Steganography.cpp @@ -0,0 +1,25 @@ +#include "Steganography.hpp" +#include "CommonDefs.hpp" +#include + +std::wstring Steganography::embed(const std::wstring& cover_text, const std::string& message) { + std::wstring encoded = ZeroWidthEncoder::encode(message); + return cover_text + CommonDefs::ZERO_WIDTH_JOINER + encoded; +} + +std::string Steganography::extract(const std::wstring& stego_text) { + // 查找分隔符 + size_t pos = stego_text.find(CommonDefs::ZERO_WIDTH_JOINER); + if (pos == std::wstring::npos) { + throw std::runtime_error("No hidden message detected"); + } + + std::wstring encoded = stego_text.substr(pos + 1); + return ZeroWidthEncoder::decode(encoded); +} + +bool Steganography::is_zero_width(wchar_t c) { + return c == CommonDefs::ZERO_WIDTH_SPACE || + c == CommonDefs::ZERO_WIDTH_NON_JOINER || + c == CommonDefs::ZERO_WIDTH_JOINER; +} \ No newline at end of file diff --git a/others/C++/stegano_project/src/ZeroWidthEncoder.cpp b/others/C++/stegano_project/src/ZeroWidthEncoder.cpp new file mode 100644 index 0000000..07b2587 --- /dev/null +++ b/others/C++/stegano_project/src/ZeroWidthEncoder.cpp @@ -0,0 +1,41 @@ +#include "ZeroWidthEncoder.hpp" +#include "CommonDefs.hpp" +#include + +std::wstring ZeroWidthEncoder::encode(const std::string& message) { + std::wstring result; + for (char c : message) { + result += char_to_zero_width(c); + } + return result; +} + +std::string ZeroWidthEncoder::decode(const std::wstring& encoded) { + std::string result; + for (size_t i = 0; i < encoded.size(); i += 8) { + if (i + 8 > encoded.size()) break; + result += zero_width_to_char(encoded.substr(i, 8)); + } + return result; +} + +std::wstring ZeroWidthEncoder::char_to_zero_width(char c) { + std::bitset<8> bits(c); + std::wstring seq; + for (int i = 7; i >= 0; --i) { + seq += bits.test(i) ? + CommonDefs::ZERO_WIDTH_NON_JOINER : + CommonDefs::ZERO_WIDTH_SPACE; + } + return seq; +} + +char ZeroWidthEncoder::zero_width_to_char(const std::wstring& sequence) { + if (sequence.size() != 8) return 0; + + std::bitset<8> bits; + for (int i = 0; i < 8; ++i) { + bits.set(7 - i, sequence[i] == CommonDefs::ZERO_WIDTH_NON_JOINER); + } + return static_cast(bits.to_ulong()); +} \ No newline at end of file diff --git a/others/C++/stegano_project/src/main.cpp b/others/C++/stegano_project/src/main.cpp new file mode 100644 index 0000000..d9dc928 --- /dev/null +++ b/others/C++/stegano_project/src/main.cpp @@ -0,0 +1,13 @@ +#include "GUI.hpp" +#include +#include + +int main() { + // 确保控制台使用UTF-8编码 + SetConsoleOutputCP(CP_UTF8); + + MainWindow win(800, 600, "Zero-Width Steganography"); + win.show(); + + return Fl::run(); +} \ No newline at end of file