diff --git a/CMakeLists.txt b/CMakeLists.txt index 36e0ccd..51b1082 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) -project(transm VERSION 1.4.2 LANGUAGES CXX) +project(transm VERSION 1.5.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/client/client.cpp b/client/client.cpp index 2d8f338..3b6001d 100644 --- a/client/client.cpp +++ b/client/client.cpp @@ -58,8 +58,9 @@ void CClient::print_help(bool detail) if (!detail) { TLOGW("Get|Who|Where|Ls|Sub|Fetch|Up|Down|UpTask|DownTask"); - TLOGI("You can use 'h' to show cmd's detail."); - TLOGI("You can use 'end' or 'ctrl-c' to exit."); + TLOGI(" to show cmd's detail."); + TLOGI("use or to exit."); + TLOGI("use or to oper encrypt( to view)."); return; } @@ -125,8 +126,8 @@ void CClient::print_help(bool detail) void CClient::free_buf_manual(CFrameBuffer* buf) { if (buf == nullptr) { - return; - } + return; + } delete buf->data_; buf->data_ = nullptr; } @@ -188,6 +189,23 @@ void CClient::run(const std::string& ip, const std::string& port, const std::str continue; } + if (cmd_input == "on" || cmd_input == "On") { + set_encrypt(true); + TLOGI("Encrypt is on."); + continue; + } + + if (cmd_input == "?") { + TLOGI("Encrypt is {}.", get_encrypt_status() ? "on" : "off"); + continue; + } + + if (cmd_input == "off" || cmd_input == "Off") { + set_encrypt(false); + TLOGI("Encrypt is off."); + continue; + } + if (cmd_input == "end" || cmd_input == "End") { th_run_ = false; std::this_thread::sleep_for(std::chrono::milliseconds(10)); @@ -1340,7 +1358,7 @@ void CClient::send_file_data_th(const char* keys) TLOGE("Stop Trans {} To {} failed.", t->cur_file_, str_key); return; } - + free_buf_manual(buf.get()); buf->type_ = TYPE_TRANS_FILE; buf->mark_ = 1; diff --git a/test/main.cxx b/test/main.cxx index b37f691..d566121 100644 --- a/test/main.cxx +++ b/test/main.cxx @@ -1,8 +1,174 @@ #include +#include #include #include -int main() +#ifdef USE_BOOST +#include +namespace fs = boost::filesystem; +#else +#include +namespace fs = std::filesystem; +#endif + +const size_t BLOCK_SIZE = 102400; // 100KB块大小 +const size_t IV_SIZE = 16; // 随机值大小 + +/* +测试环境: +Microsoft Windows 10 Professional (x64) Build 19045.5608 (22H2) +13th Gen Intel(R) Core(TM) i5-13500H 3200.0 MHz +Debug模式 tinyaes 加密解密测试速度: +========================================= +File size: 630239232 bytes (601.043 MB) +Effective block size: 102384 bytes +IV size: 16 bytes +Blocks processed: 6156 +Total encryption time: 41887336 μs (14.349 MB/s) +Total decryption time: 41822620 μs (14.3712 MB/s) +Decrypted file: "D:\\1_decrypted.iso" +Data verification: PASSED +========================================= +Release模式 tinyaes 加密解密测试速度: +========================================= +File size: 630239232 bytes (601.043 MB) +Effective block size: 102384 bytes +IV size: 16 bytes +Blocks processed: 6156 +Total encryption time: 8367460 μs (71.831 MB/s) +Total decryption time: 8150036 μs (73.7473 MB/s) +Decrypted file: "D:\\1_decrypted.iso" +Data verification: PASSED +========================================= +*/ + +void test_speed(const char* input_file) +{ + // 检查输入文件 + if (!fs::exists(input_file)) { + std::cerr << "Input file not found: " << input_file << std::endl; + return; + } + + size_t file_size = fs::file_size(input_file); + if (file_size == 0) { + std::cerr << "Input file is empty" << std::endl; + return; + } + + // 准备密钥 + std::string key = "test_speed_key"; + uint8_t ik[32]{}; + hash(key.c_str(), ik); + + // 准备解密后的输出文件 + fs::path decrypted_path = fs::path(input_file) + .replace_filename(fs::path(input_file).stem().string() + "_decrypted" + + fs::path(input_file).extension().string()); + + std::ofstream decrypted_file(decrypted_path, std::ios::binary); + if (!decrypted_file) { + std::cerr << "Failed to create decrypted file" << std::endl; + return; + } + + // 打开输入文件 + std::ifstream in_file(input_file, std::ios::binary); + if (!in_file) { + std::cerr << "Failed to open input file" << std::endl; + return; + } + + // 测试数据缓冲区(额外预留16字节空间) + std::vector original_block(BLOCK_SIZE); + std::vector processing_block(BLOCK_SIZE + IV_SIZE); // 加密/解密处理缓冲区 + + size_t total_bytes = 0; + size_t blocks_processed = 0; + bool verification_passed = true; + + // 计时变量 + auto total_encrypt_time = std::chrono::microseconds(0); + auto total_decrypt_time = std::chrono::microseconds(0); + + while (in_file) { + // 读取原始数据块(注意实际读取量比BLOCK_SIZE少16字节) + in_file.read(reinterpret_cast(original_block.data()), BLOCK_SIZE - IV_SIZE); + size_t bytes_read = in_file.gcount(); + if (bytes_read == 0) + break; + + // 准备加密缓冲区(前16字节留给随机值) + memcpy(processing_block.data() + IV_SIZE, original_block.data(), bytes_read); + + // 加密计时 + auto start_encrypt = std::chrono::high_resolution_clock::now(); + if (!encrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) { + std::cerr << "Encryption failed at block " << blocks_processed << std::endl; + verification_passed = false; + break; + } + auto end_encrypt = std::chrono::high_resolution_clock::now(); + total_encrypt_time += + std::chrono::duration_cast(end_encrypt - start_encrypt); + + // 解密计时(使用加密后的数据) + auto start_decrypt = std::chrono::high_resolution_clock::now(); + if (!decrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) { + std::cerr << "Decryption failed at block " << blocks_processed << std::endl; + verification_passed = false; + break; + } + auto end_decrypt = std::chrono::high_resolution_clock::now(); + total_decrypt_time += + std::chrono::duration_cast(end_decrypt - start_decrypt); + + // 验证解密结果(比较解密后的数据部分) + if (memcmp(original_block.data(), processing_block.data() + IV_SIZE, bytes_read) != 0) { + std::cerr << "Data mismatch at block " << blocks_processed << std::endl; + verification_passed = false; + break; + } + + // 写入解密后的数据(只写入有效数据部分) + decrypted_file.write(reinterpret_cast(processing_block.data() + IV_SIZE), bytes_read); + + total_bytes += bytes_read; + blocks_processed++; + } + + // 关闭文件 + in_file.close(); + decrypted_file.close(); + + // 计算吞吐量(只计算有效数据部分) + double encrypt_throughput = + (double)total_bytes / (1024 * 1024) / (total_encrypt_time.count() / 1000000.0); + double decrypt_throughput = + (double)total_bytes / (1024 * 1024) / (total_decrypt_time.count() / 1000000.0); + + // 输出结果 + std::cout << "\nOptimized Block Encryption/Decryption Test\n"; + std::cout << "=========================================\n"; + std::cout << "File size: " << file_size << " bytes (" << (double)file_size / (1024 * 1024) << " MB)\n"; + std::cout << "Effective block size: " << (BLOCK_SIZE - IV_SIZE) << " bytes\n"; + std::cout << "IV size: " << IV_SIZE << " bytes\n"; + std::cout << "Blocks processed: " << blocks_processed << "\n"; + std::cout << "Total encryption time: " << total_encrypt_time.count() << " μs (" << encrypt_throughput + << " MB/s)\n"; + std::cout << "Total decryption time: " << total_decrypt_time.count() << " μs (" << decrypt_throughput + << " MB/s)\n"; + std::cout << "Decrypted file: " << decrypted_path << "\n"; + std::cout << "Data verification: " << (verification_passed ? "PASSED" : "FAILED") << "\n"; + std::cout << "=========================================\n"; + + // 如果验证失败,删除可能不正确的解密文件 + if (!verification_passed) { + fs::remove(decrypted_path); + } +} + +void base_test() { std::string key = "sss"; uint8_t ik[32]{}; @@ -15,13 +181,18 @@ int main() std::cout << encrypt(ik, (uint8_t*)msg, len + offset) << std::endl; std::cout << msg + offset << std::endl; - uint8_t ik2[32]{}; hash(key.c_str(), ik2); std::cout << decrypt(ik2, (uint8_t*)msg, len + offset) << std::endl; std::cout << msg + offset << std::endl; + delete[] msg; +} + +int main() +{ + test_speed("D:\\1.iso"); return 0; } \ No newline at end of file diff --git a/util/util.cpp b/util/util.cpp index 3633732..00b43c5 100644 --- a/util/util.cpp +++ b/util/util.cpp @@ -9,6 +9,7 @@ CTransProtocal::CTransProtocal() = default; constexpr uint8_t kz = 16; +static bool use_encrypt = true; CTransProtocal::~CTransProtocal() = default; /* @@ -141,17 +142,17 @@ void serialize(CMessageInfo& msg_info, char** out_buf, int& len) info.str = localtou8(info.str); // 计算总长度 - len = sizeof(int) * 4 + info.id.size() + info.uuid.size() + info.str.size() + info.data.size() + kz; + len = sizeof(int) * 4 + info.id.size() + info.uuid.size() + info.str.size() + info.data.size() + kz + 1; // 《这里为了效率》,认为如果 *out_buf 不为空,则直接使用,且长度符合要求 - // 调用方负责确保内存一致性和可用性。 + // 调用方负责确保内存够用性(len小于最大长度)和可用性。 // 即,如果调用方及高频率调用 serialize, 且每次 len 固定就复用内存,完了再释放。 // 低频率或者 len 不固定时,每次都释放内存,并置 nullptr。 if (*out_buf == nullptr) { - *out_buf = new char[len] {}; // 分配内存(调用方负责释放) + *out_buf = new char[len]{}; // 分配内存(调用方负责释放) } - char* ptr = *out_buf + kz; + char* ptr = *out_buf + kz + 1; // 序列化 cmd int id_size = static_cast(info.id.size()); @@ -180,29 +181,36 @@ void serialize(CMessageInfo& msg_info, char** out_buf, int& len) ptr += sizeof(int); memcpy(ptr, info.data.data(), o_size); - uint8_t ik[32]{}; - hash(msg_info.id.c_str(), ik); - if (!encrypt(ik, (uint8_t*)(*out_buf), len)) { + char* c = *out_buf; + if (!use_encrypt) { + c[0] = 0x00; return; } + uint8_t ik[32]{}; + hash(msg_info.id.c_str(), ik); + encrypt(ik, (uint8_t*)(*out_buf + 1), len); + c[0] = 0x01; } bool deserialize(char* data, int len, CMessageInfo& msg_info) { - if (len < kz) { - return false; - } - - uint8_t ik[32]{}; - hash(msg_info.id.c_str(), ik); - if (!decrypt(ik, (uint8_t*)(data), len)) { + if (len < (kz + 1)) { return false; } auto& info = msg_info; - char* ptr = data + kz; + char* ptr = data + kz + 1; + uint8_t ie = data[0]; int remaining = len; + if (ie != 0x00) { + uint8_t ik[32]{}; + hash(msg_info.id.c_str(), ik); + if (!decrypt(ik, (uint8_t*)(data + 1), len)) { + return false; + } + } + // 反序列化 cmd if (remaining < static_cast(sizeof(int))) { return false; @@ -340,6 +348,16 @@ bool decrypt(const uint8_t* k, uint8_t* m, size_t len) return true; } +void set_encrypt(bool encrypt) +{ + use_encrypt = encrypt; +} + +bool get_encrypt_status() +{ + return use_encrypt; +} + CMessageInfo::CMessageInfo(const std::string& id) : id(id) { } diff --git a/util/util.h b/util/util.h index 81c7b6b..ccaab65 100644 --- a/util/util.h +++ b/util/util.h @@ -61,6 +61,8 @@ void hash(const char* data, uint8_t k[32]); void rdm(uint8_t* o, size_t size); bool encrypt(const uint8_t* k, uint8_t* m, size_t len); bool decrypt(const uint8_t* k, uint8_t* m, size_t len); +void set_encrypt(bool encrypt); +bool get_encrypt_status(); using namespace ofen; class CFrameBuffer