remove:不使用boost filesystem.

This commit is contained in:
taynpg 2025-05-18 00:25:33 +08:00
parent 15085a1f8f
commit 655cfe6fad
21 changed files with 393 additions and 272 deletions

View File

@ -1,6 +1,6 @@
{ {
"files.autoSave": "onFocusChange", "files.autoSave": "onFocusChange",
"editor.fontSize": 13, "editor.fontSize": 14,
"editor.fontFamily": "'Monaspace Krypton Light', 'Monaspace Krypton Light', 'Monaspace Krypton Light'", "editor.fontFamily": "'Monaspace Krypton Light', 'Monaspace Krypton Light', 'Monaspace Krypton Light'",
"terminal.integrated.fontFamily": "Monaspace Krypton Light", "terminal.integrated.fontFamily": "Monaspace Krypton Light",
"cmake.configureOnOpen": true, "cmake.configureOnOpen": true,

View File

@ -20,12 +20,7 @@ add_compile_options(-finput-charset=utf-8)
add_compile_options(-fexec-charset=gbk) add_compile_options(-fexec-charset=gbk)
add_compile_options(-Wa,-mbig-obj) add_compile_options(-Wa,-mbig-obj)
set(COMPILER_ID "mingw") set(COMPILER_ID "mingw")
endif() include(config/Mingw.cmake)
if(DEFINED USE_BOOST)
message(STATUS "use boost library ${USE_BOOST}")
add_definitions(-DUSE_BOOST)
include(config/MBoost.cmake)
endif() endif()
string(TOLOWER ${COMPILER_ID} COMPILER_ID) string(TOLOWER ${COMPILER_ID} COMPILER_ID)
@ -70,6 +65,19 @@ else()
add_subdirectory(http-server) add_subdirectory(http-server)
endif() endif()
if(WIN32)
execute_process(COMMAND cmd /c ver
OUTPUT_VARIABLE VER_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(VER_OUTPUT MATCHES "XP")
message(STATUS "Windows XP platform.")
add_definitions(-D_WIN32_WINNT=0x0501)
else()
message(STATUS "Windows NT platform.")
add_definitions(-D_WIN32_WINNT=0x0601)
endif()
endif()
if (DEFINED USE_TRANSM_TEST) if (DEFINED USE_TRANSM_TEST)
message(STATUS "USE USE_TRANSM_TEST ${USE_TRANSM_TEST}") message(STATUS "USE USE_TRANSM_TEST ${USE_TRANSM_TEST}")
add_definitions(-DUSE_TRANSM_TEST) add_definitions(-DUSE_TRANSM_TEST)
@ -104,13 +112,9 @@ else()
install(TARGETS tss-http DESTINATION bin) install(TARGETS tss-http DESTINATION bin)
endif() endif()
if (DEFINED USE_BOOST) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
install(FILES ${MINGW32_DLLS} DESTINATION bin) install(FILES ${MINGW32_DLLS} DESTINATION bin)
endif() endif()
if (DEFINED USE_GUI)
message(STATUS "USE GUI ${USE_GUI}")
#add_subdirectory(gui)
endif()
# ********************************************************** pack infomation # ********************************************************** pack infomation
if(CMAKE_SIZEOF_VOID_P EQUAL 8) if(CMAKE_SIZEOF_VOID_P EQUAL 8)

View File

@ -6,11 +6,6 @@ set(CMAKE_CXX_STANDARD 17)
if (MSVC) if (MSVC)
add_compile_options(/source-charset:utf-8) add_compile_options(/source-charset:utf-8)
endif() endif()
if(DEFINED USE_BOOST)
message(STATUS "tsc use boost lib.")
include_directories(${MBOOST_INCLUDE_DIR})
link_directories(${MBOOST_LIB_DIR})
endif()
add_executable(tsc main.cpp client.h client.cpp config.h config.cpp) add_executable(tsc main.cpp client.h client.cpp config.h config.cpp)
target_link_libraries(tsc PRIVATE trans_net trans_util filecomplete) target_link_libraries(tsc PRIVATE trans_net trans_util filecomplete)
@ -20,10 +15,7 @@ endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows") if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
target_link_libraries(tsc PRIVATE ws2_32 wsock32) target_link_libraries(tsc PRIVATE ws2_32 wsock32)
endif() endif()
if(DEFINED USE_BOOST)
target_link_directories(tsc PRIVATE ${MBOOST_LIB_DIR})
target_link_libraries(tsc PRIVATE ${MBOOST_LIBS})
endif()
if (DEFINED GRAB_CRASH) if (DEFINED GRAB_CRASH)
message(STATUS "tsc link crashelper") message(STATUS "tsc link crashelper")
target_link_libraries(tsc PRIVATE crashelper) target_link_libraries(tsc PRIVATE crashelper)

View File

@ -1,19 +1,13 @@
#include "client.h" #include "client.h"
#include <filesystem>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <of_path.h> #include <of_path.h>
#include <of_str.h> #include <of_str.h>
#include <of_util.h> #include <of_util.h>
#include <version.h> #include <version.h>
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
#endif
TransmClient::TransmClient() : msg_info_("") TransmClient::TransmClient() : msg_info_("")
{ {
@ -126,7 +120,8 @@ void TransmClient::print_help(bool detail)
TLOGI("{}", sp); TLOGI("{}", sp);
} }
bool TransmClient::base_init(const std::string& ip, const std::string& port, const std::string& config_dir) bool TransmClient::base_init(const std::string& ip, const std::string& port,
const std::string& config_dir)
{ {
fs::path fp(config_dir); fs::path fp(config_dir);
config_path_ = fp.append("history.txt").string(); config_path_ = fp.append("history.txt").string();
@ -158,7 +153,8 @@ bool TransmClient::base_init(const std::string& ip, const std::string& port, con
return true; return true;
} }
void TransmClient::run(const std::string& ip, const std::string& port, const std::string& config_dir) void TransmClient::run(const std::string& ip, const std::string& port,
const std::string& config_dir)
{ {
if (!base_init(ip, port, config_dir)) { if (!base_init(ip, port, config_dir)) {
return; return;
@ -178,7 +174,8 @@ void TransmClient::run(const std::string& ip, const std::string& port, const std
break; break;
} }
if (!th_run_ || !client_->is_normal()) { if (!th_run_ || !client_->is_normal()) {
TLOGW("The link has been closed and cannot be continued. It will automatically exit."); TLOGW("The link has been closed and cannot be continued. It will "
"automatically exit.");
break; break;
} }
std::string cmd_input(readline); std::string cmd_input(readline);
@ -222,11 +219,13 @@ void TransmClient::run(const std::string& ip, const std::string& port, const std
TLOGD("At => {}", COfPath::to_full(".")); TLOGD("At => {}", COfPath::to_full("."));
continue; continue;
} }
if (cmd_input == "Get" || cmd_input == "get" || cmd_input == "g" || cmd_input == "G") { if (cmd_input == "Get" || cmd_input == "get" || cmd_input == "g" ||
cmd_input == "G") {
get_clients(); get_clients();
continue; continue;
} }
if (cmd_input == "Clear" || cmd_input == "clear" || cmd_input == "c" || cmd_input == "C") { if (cmd_input == "Clear" || cmd_input == "clear" || cmd_input == "c" ||
cmd_input == "C") {
cmd_clear_submited(); cmd_clear_submited();
continue; continue;
} }
@ -274,7 +273,8 @@ void TransmClient::run(const std::string& ip, const std::string& port, const std
} }
#ifdef USE_TRANSM_TEST #ifdef USE_TRANSM_TEST
bool TransmClient::connect_for_test(const std::string& ip, const std::string& port, bool TransmClient::connect_for_test(const std::string& ip,
const std::string& port,
const std::string& config_dir) const std::string& config_dir)
{ {
if (!base_init(ip, port, config_dir)) { if (!base_init(ip, port, config_dir)) {
@ -384,7 +384,8 @@ bool TransmClient::cmd_sub_list(const std::string& param)
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
for (const auto& item : up_) { for (const auto& item : up_) {
if (item.second->trans_state_ == TRANS_REDAY || item.second->trans_state_ == TRANS_ING) { if (item.second->trans_state_ == TRANS_REDAY ||
item.second->trans_state_ == TRANS_ING) {
TLOGW("Have Task Upping, Please wait!"); TLOGW("Have Task Upping, Please wait!");
return false; return false;
} }
@ -436,7 +437,8 @@ bool TransmClient::cmd_clear_submited()
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
for (const auto& item : up_) { for (const auto& item : up_) {
if (item.second->trans_state_ == TRANS_REDAY || item.second->trans_state_ == TRANS_ING) { if (item.second->trans_state_ == TRANS_REDAY ||
item.second->trans_state_ == TRANS_ING) {
TLOGW("Have Task Upping, Please wait!"); TLOGW("Have Task Upping, Please wait!");
return false; return false;
} }
@ -520,13 +522,15 @@ bool TransmClient::cmd_upload_files(const std::string& param)
return true; return true;
} }
bool TransmClient::down_one_file(int remote_id, const std::string& file, const std::string& local_dir) bool TransmClient::down_one_file(int remote_id, const std::string& file,
const std::string& local_dir)
{ {
std::string ret_id{}; std::string ret_id{};
std::string ret_uuid{}; std::string ret_uuid{};
if (clients_.count(remote_id) == 0) { if (clients_.count(remote_id) == 0) {
TLOGW("{} No Index Found {}, Try {}", __LINE__, remote_id, list_server_id_); TLOGW("{} No Index Found {}, Try {}", __LINE__, remote_id,
list_server_id_);
ret_id = list_server_id_; ret_id = list_server_id_;
ret_uuid = list_server_uuid_; ret_uuid = list_server_uuid_;
} else { } else {
@ -541,13 +545,17 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
if (local_dir.empty()) { if (local_dir.empty()) {
down_->cur_file_ = COfPath::to_full(remote_file.filename().string()); down_->cur_file_ = COfPath::to_full(remote_file.filename().string());
} else { } else {
down_->cur_file_ = fs::path(local_dir).append(remote_file.filename().string()).string(); down_->cur_file_ = fs::path(local_dir)
.append(remote_file.filename().string())
.string();
} }
// 这里要先检查羁绊 // 这里要先检查羁绊
if (ret_uuid == uuid_ && COfPath::is_same_dir(remote_file.string(), down_->cur_file_)) { if (ret_uuid == uuid_ &&
COfPath::is_same_dir(remote_file.string(), down_->cur_file_)) {
// 处在同一个机器上的同目录下 // 处在同一个机器上的同目录下
TLOGE("You Can't Operate File In Same Dir And In Same Machine.", down_->cur_remote_file_); TLOGE("You Can't Operate File In Same Dir And In Same Machine.",
down_->cur_remote_file_);
return false; return false;
} }
@ -565,7 +573,8 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
msg_info.str = file; msg_info.str = file;
serialize(msg_info, &buf->data_, buf->len_); serialize(msg_info, &buf->data_, buf->len_);
if (!send_frame(buf.get())) { if (!send_frame(buf.get())) {
TLOGE("{} request open file [{}] send failed.", __FUNCTION__, down_->cur_remote_file_); TLOGE("{} request open file [{}] send failed.", __FUNCTION__,
down_->cur_remote_file_);
down_->cur_remote_id_.clear(); down_->cur_remote_id_.clear();
down_->cur_remote_file_.clear(); down_->cur_remote_file_.clear();
return false; return false;
@ -575,7 +584,8 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
cur_down_size_ = 0; cur_down_size_ = 0;
float percent = 0.0; float percent = 0.0;
fc_disable_cur(); fc_disable_cur();
while (down_->trans_state_ != TRANS_DONE && down_->trans_state_ != TRANS_FAILED) { while (down_->trans_state_ != TRANS_DONE &&
down_->trans_state_ != TRANS_FAILED) {
std::this_thread::sleep_for(std::chrono::milliseconds(down_check_wait)); std::this_thread::sleep_for(std::chrono::milliseconds(down_check_wait));
if (cur_file_size_ > 0) { if (cur_file_size_ > 0) {
percent = (float)cur_down_size_ / cur_file_size_; percent = (float)cur_down_size_ / cur_file_size_;
@ -593,7 +603,8 @@ bool TransmClient::down_one_file(int remote_id, const std::string& file, const s
} }
fc_enable_cur(); fc_enable_cur();
if (cur_down_size_ > 0 && cur_file_size_ == cur_down_size_) { if (cur_down_size_ > 0 && cur_file_size_ == cur_down_size_) {
TLOGW("down one file success, total:[{}/{}]", cur_down_size_, cur_file_size_); TLOGW("down one file success, total:[{}/{}]", cur_down_size_,
cur_file_size_);
return true; return true;
} else { } else {
TLOGW("down one file {} failed, size not matched.", down_->cur_file_); TLOGW("down one file {} failed, size not matched.", down_->cur_file_);
@ -754,8 +765,8 @@ bool TransmClient::cmd_sub_task(const std::string& param, bool is_send)
return true; return true;
} }
bool TransmClient::variable_and_parse_files(const std::string& content, bool TransmClient::variable_and_parse_files(
std::map<std::string, std::string>& files) const std::string& content, std::map<std::string, std::string>& files)
{ {
auto vec = COfStr::split(content, "\n"); auto vec = COfStr::split(content, "\n");
bool valid = true; bool valid = true;
@ -781,7 +792,8 @@ bool TransmClient::variable_and_parse_files(const std::string& content,
return valid; return valid;
} }
bool TransmClient::down_update_file(const std::map<std::string, std::string>& files) bool TransmClient::down_update_file(
const std::map<std::string, std::string>& files)
{ {
std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>(); std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
buf->tid_ = list_server_id_; buf->tid_ = list_server_id_;
@ -813,7 +825,8 @@ bool TransmClient::down_update_file(const std::map<std::string, std::string>& fi
return suc; return suc;
} }
bool TransmClient::get_dir_files(const std::string& dir, std::string& out, std::string& error) bool TransmClient::get_dir_files(const std::string& dir, std::string& out,
std::string& error)
{ {
fs::path p(dir); fs::path p(dir);
out.clear(); out.clear();
@ -872,7 +885,8 @@ bool TransmClient::cmd_down_list(const std::string& param)
} }
int index = std::stoi(tvec[0]); int index = std::stoi(tvec[0]);
std::string lists = tvec[1]; std::string lists = tvec[1];
std::string local = tvec.size() > 2 ? COfPath::to_full(tvec[2]) : COfPath::to_full(""); std::string local =
tvec.size() > 2 ? COfPath::to_full(tvec[2]) : COfPath::to_full("");
if (!clients_.count(index)) { if (!clients_.count(index)) {
TLOGE("{} No Index Found {}.", __LINE__, index); TLOGE("{} No Index Found {}.", __LINE__, index);
@ -1214,10 +1228,12 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
up_[buf->fid_] = std::make_shared<TransInfomation>(); up_[buf->fid_] = std::make_shared<TransInfomation>();
up_[buf->fid_]->cur_file_ = msg_info.str; up_[buf->fid_]->cur_file_ = msg_info.str;
up_[buf->fid_]->file_.open(up_[buf->fid_]->cur_file_, std::ios::in | std::ios::binary); up_[buf->fid_]->file_.open(up_[buf->fid_]->cur_file_,
std::ios::in | std::ios::binary);
up_[buf->fid_]->trans_state_ = TRANS_REDAY; up_[buf->fid_]->trans_state_ = TRANS_REDAY;
if (!up_[buf->fid_]->file_.is_open()) { if (!up_[buf->fid_]->file_.is_open()) {
TLOGE("Ready Send File {} Open Failed.", up_[buf->fid_]->cur_file_); TLOGE("Ready Send File {} Open Failed.",
up_[buf->fid_]->cur_file_);
buf->type_ = TYPE_OPEN_FAILED; buf->type_ = TYPE_OPEN_FAILED;
std::swap(buf->tid_, buf->fid_); std::swap(buf->tid_, buf->fid_);
if (!send_frame(buf)) { if (!send_frame(buf)) {
@ -1229,7 +1245,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
keys = buf->fid_; keys = buf->fid_;
} }
if (!keys.empty()) { if (!keys.empty()) {
ths_.emplace_back([this, keys]() { send_file_data_th(keys.c_str()); }); ths_.emplace_back(
[this, keys]() { send_file_data_th(keys.c_str()); });
} }
break; break;
} }
@ -1320,7 +1337,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
if (update_list_th_.joinable()) { if (update_list_th_.joinable()) {
update_list_th_.join(); update_list_th_.join();
} }
update_list_th_ = std::thread([this, files]() { down_update_file(files); }); update_list_th_ =
std::thread([this, files]() { down_update_file(files); });
break; break;
} }
case TYPE_CONFIRM_UPDATE_LIST: { case TYPE_CONFIRM_UPDATE_LIST: {
@ -1346,7 +1364,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
break; break;
} }
case TYPE_BUSY_UPDATE_LIST: { case TYPE_BUSY_UPDATE_LIST: {
TLOGI("remote {} are busy, will not exec task {}", buf->fid_, list_file_); TLOGI("remote {} are busy, will not exec task {}", buf->fid_,
list_file_);
break; break;
} }
case TYPE_FILE_INFO: { case TYPE_FILE_INFO: {
@ -1371,7 +1390,8 @@ void TransmClient::handle_frame(CFrameBuffer* buf)
break; break;
} }
default: default:
TLOGE("UnSupport Type {}, Current Version v{}", static_cast<int>(buf->type_), VERSION_NUM); TLOGE("UnSupport Type {}, Current Version v{}",
static_cast<int>(buf->type_), VERSION_NUM);
break; break;
} }
} }
@ -1419,8 +1439,8 @@ void TransmClient::send_file_data_th(const char* keys)
#endif #endif
std::string info_result = plat + "," + str_size + "," + str_perm; std::string info_result = plat + "," + str_size + "," + str_perm;
TLOGI("To {} File Size: {} [{}], permissions:{}", str_key, ofen::OfUtil::get_file_size(size), size, TLOGI("To {} File Size: {} [{}], permissions:{}", str_key,
str_perm); ofen::OfUtil::get_file_size(size), size, str_perm);
msg_info.str = info_result; msg_info.str = info_result;
serialize(msg_info, &buf->data_, buf->len_); serialize(msg_info, &buf->data_, buf->len_);
if (!send_frame(buf.get())) { if (!send_frame(buf.get())) {
@ -1493,13 +1513,15 @@ void TransmClient::judget_down_active()
} }
} }
std::string TransmClient::variable_handle(const std::string& task_list_path, const std::string& source, std::string TransmClient::variable_handle(const std::string& task_list_path,
const std::string& source,
bool is_local) bool is_local)
{ {
std::string result(source); std::string result(source);
// 支持的变量如下: // 支持的变量如下:
// ${HOME} 用户目录(发送端接收端均支持) // ${HOME} 用户目录(发送端接收端均支持)
// ${CURRENT} 任务文件所在目录(该变量仅支持发送端,因为接收端没有任务文件所在路径) // ${CURRENT}
// 任务文件所在目录(该变量仅支持发送端,因为接收端没有任务文件所在路径)
if (is_local && source.find("${HOME}") != std::string::npos) { if (is_local && source.find("${HOME}") != std::string::npos) {
result = COfStr::replace(result, "${HOME}", COfPath::get_home()); result = COfStr::replace(result, "${HOME}", COfPath::get_home());
} }
@ -1514,7 +1536,8 @@ std::string TransmClient::variable_handle(const std::string& task_list_path, con
return result; return result;
} }
std::string TransmClient::handle_user_select(const std::unordered_map<int, std::string>& source, bool is_send) std::string TransmClient::handle_user_select(
const std::unordered_map<int, std::string>& source, bool is_send)
{ {
std::string handled_content{}; std::string handled_content{};
std::string input{}; std::string input{};
@ -1558,11 +1581,13 @@ std::string TransmClient::handle_user_select(const std::unordered_map<int, std::
handled_content.append(source.at(key) + "\n"); handled_content.append(source.at(key) + "\n");
} else { } else {
// 如果mre中没有这个key // 如果mre中没有这个key
TLOGE("Invalid input, please enter valid numbers or '0' for all."); TLOGE("Invalid input, please enter valid numbers or "
"'0' for all.");
break; break;
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
TLOGE("Invalid input, please enter valid numbers or '0' for all."); TLOGE("Invalid input, please enter valid numbers or '0' "
"for all.");
break; break;
} }
} }
@ -1578,7 +1603,8 @@ CFileOpr::CFileOpr() = default;
CFileOpr::~CFileOpr() = default; CFileOpr::~CFileOpr() = default;
bool CFileOpr::get_file_list(const std::string& input, std::vector<std::string>& out) bool CFileOpr::get_file_list(const std::string& input,
std::vector<std::string>& out)
{ {
out.clear(); out.clear();
auto backup = COfStr::trim(input); auto backup = COfStr::trim(input);
@ -1600,14 +1626,17 @@ bool CFileOpr::get_file_list(const std::string& input, std::vector<std::string>&
} }
#endif #endif
if (ret.find("?") != std::string::npos || ret.find("*") != std::string::npos) { if (ret.find("?") != std::string::npos ||
ret.find("*") != std::string::npos) {
auto fv = COfPath::match_files(ret); auto fv = COfPath::match_files(ret);
for (const auto& v : fv) { for (const auto& v : fv) {
TLOGI("match file: {}", v); TLOGI("match file: {}", v);
} }
std::string cof; std::string cof;
while (true) { while (true) {
TLOGI("Detected regex's file (num = {}), please confirm if it is correct? ", fv.size()); TLOGI("Detected regex's file (num = {}), please confirm if it "
"is correct? ",
fv.size());
TLOGW("support input in [y,Y,end]", fv.size()); TLOGW("support input in [y,Y,end]", fv.size());
std::getline(std::cin, cof); std::getline(std::cin, cof);
if (cof == "y" || cof == "Y") { if (cof == "y" || cof == "Y") {

View File

@ -45,7 +45,8 @@ public:
~TransmClient(); ~TransmClient();
public: public:
void run(const std::string& ip, const std::string& port, const std::string& config_dir); void run(const std::string& ip, const std::string& port,
const std::string& config_dir);
bool get_clients(); bool get_clients();
bool cmd_fetch_files(const std::string& param); bool cmd_fetch_files(const std::string& param);
bool cmd_sub_list(const std::string& param); bool cmd_sub_list(const std::string& param);
@ -56,11 +57,14 @@ public:
bool cmd_down_list(const std::string& param); bool cmd_down_list(const std::string& param);
private: private:
bool variable_and_parse_files(const std::string& content, std::map<std::string, std::string>& files); bool variable_and_parse_files(const std::string& content,
std::map<std::string, std::string>& files);
bool down_update_file(const std::map<std::string, std::string>& files); bool down_update_file(const std::map<std::string, std::string>& files);
bool get_dir_files(const std::string& dir, std::string& out, std::string& error); bool get_dir_files(const std::string& dir, std::string& out,
std::string& error);
void report_trans_ret(TransState state, const std::string& key = ""); void report_trans_ret(TransState state, const std::string& key = "");
bool down_one_file(int remote_id, const std::string& file, const std::string& local_dir = ""); bool down_one_file(int remote_id, const std::string& file,
const std::string& local_dir = "");
private: private:
bool send_frame(CFrameBuffer* buf); bool send_frame(CFrameBuffer* buf);
@ -71,15 +75,19 @@ private:
std::string read_uuid(); std::string read_uuid();
void get_id(); void get_id();
void print_help(bool detail); void print_help(bool detail);
bool base_init(const std::string& ip, const std::string& port, const std::string& config_dir); bool base_init(const std::string& ip, const std::string& port,
const std::string& config_dir);
private: private:
void handle_frame(CFrameBuffer* buf); void handle_frame(CFrameBuffer* buf);
void send_file_data_th(const char* keys); void send_file_data_th(const char* keys);
void hearts(); void hearts();
void judget_down_active(); void judget_down_active();
std::string variable_handle(const std::string& task_list_path, const std::string& source, bool is_local); std::string variable_handle(const std::string& task_list_path,
std::string handle_user_select(const std::unordered_map<int, std::string>& source, bool is_send); const std::string& source, bool is_local);
std::string
handle_user_select(const std::unordered_map<int, std::string>& source,
bool is_send);
private: private:
std::mutex mutex_; std::mutex mutex_;
@ -122,7 +130,8 @@ public:
}; };
public: public:
bool connect_for_test(const std::string& ip, const std::string& port, const std::string& config_dir); bool connect_for_test(const std::string& ip, const std::string& port,
const std::string& config_dir);
void disconnect_for_test(); void disconnect_for_test();
int test_index_by_id(const std::string& id); int test_index_by_id(const std::string& id);
std::string test_get_own_id() const; std::string test_get_own_id() const;
@ -141,5 +150,6 @@ public:
~CFileOpr(); ~CFileOpr();
public: public:
static bool get_file_list(const std::string& input, std::vector<std::string>& out); static bool get_file_list(const std::string& input,
std::vector<std::string>& out);
}; };

View File

@ -1,14 +1,8 @@
#include "config.h" #include "config.h"
#include <cassert> #include <cassert>
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem> #include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
#endif
ClientConfig::ClientConfig() ClientConfig::ClientConfig()
{ {
@ -59,7 +53,8 @@ bool ClientConfig::read_ini(std::vector<TransmSet>& set)
return true; return true;
} }
long ClientConfig::have_ini(const std::vector<TransmSet>& set, const std::string& ip, long port) long ClientConfig::have_ini(const std::vector<TransmSet>& set,
const std::string& ip, long port)
{ {
long id = -1; long id = -1;
for (const auto& item : set) { for (const auto& item : set) {
@ -78,13 +73,15 @@ bool ClientConfig::write_ini(const std::vector<TransmSet>& set)
std::string key = "GROUP" + std::to_string(start); std::string key = "GROUP" + std::to_string(start);
ini_handle_.SetValue(key.c_str(), "IP", set[start].ip.c_str()); ini_handle_.SetValue(key.c_str(), "IP", set[start].ip.c_str());
ini_handle_.SetLongValue(key.c_str(), "PORT", set[start].port); ini_handle_.SetLongValue(key.c_str(), "PORT", set[start].port);
ini_handle_.SetValue(key.c_str(), "COMMENT", set[start].comment.c_str()); ini_handle_.SetValue(key.c_str(), "COMMENT",
set[start].comment.c_str());
} }
ini_handle_.SaveFile(config_path_.c_str()); ini_handle_.SaveFile(config_path_.c_str());
return true; return true;
} }
long ClientConfig::append_ini(const std::string& ip, long port, const std::string& comment) long ClientConfig::append_ini(const std::string& ip, long port,
const std::string& comment)
{ {
assert(init_ == true); assert(init_ == true);
long id = -1; long id = -1;
@ -116,15 +113,17 @@ bool ClientConfig::remove_ini(long num)
if (!read_ini(set)) { if (!read_ini(set)) {
return false; return false;
} }
set.erase( set.erase(std::remove_if(
std::remove_if(set.begin(), set.end(), [&num](const TransmSet& item) { return item.grp_id == num; }), set.begin(), set.end(),
[&num](const TransmSet& item) { return item.grp_id == num; }),
set.end()); set.end());
ini_handle_.Reset(); ini_handle_.Reset();
ini_handle_.SetLongValue("BASE", "GROUPS", static_cast<long>(set.size())); ini_handle_.SetLongValue("BASE", "GROUPS", static_cast<long>(set.size()));
return write_ini(set); return write_ini(set);
} }
bool ClientConfig::get_ini(const std::vector<TransmSet>& set, long num, TransmSet& use) bool ClientConfig::get_ini(const std::vector<TransmSet>& set, long num,
TransmSet& use)
{ {
bool find = false; bool find = false;
for (const auto& item : set) { for (const auto& item : set) {
@ -154,7 +153,8 @@ bool ClientConfig::save_last_use(const std::string& ip, long port)
bool ClientConfig::get_last_use(std::string& ip, long& port) bool ClientConfig::get_last_use(std::string& ip, long& port)
{ {
assert(init_ == true); assert(init_ == true);
if (!ini_handle_.KeyExists("Base", "LastUseIP") || !ini_handle_.KeyExists("Base", "LastUsePort")) { if (!ini_handle_.KeyExists("Base", "LastUseIP") ||
!ini_handle_.KeyExists("Base", "LastUsePort")) {
TLOGE("Not Found Last Use Record."); TLOGE("Not Found Last Use Record.");
return false; return false;
} }

View File

@ -17,36 +17,40 @@
#endif #endif
#if defined(GRAB_CRASH) #if defined(GRAB_CRASH)
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem> #include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
#endif
#include <crashelper.h> #include <crashelper.h>
#endif #endif
std::shared_ptr<ClientConfig> g_Config = nullptr; std::shared_ptr<ClientConfig> g_Config = nullptr;
int parse_cmd(int argc, char** argv, CmdParam& param) int parse_cmd(int argc, char** argv, CmdParam& param)
{ {
std::string intro(fmt::format("tsc cmd introduce, version: {}\nopensource: {}", VERSION_NUM, VERSION_URL)); std::string intro(
fmt::format("tsc cmd introduce, version: {}\nopensource: {}",
VERSION_NUM, VERSION_URL));
CLI::App app(intro); CLI::App app(intro);
app.add_option("-u, --use", param.use_config, "使用服务器地址组(值为使用--show中显示的序号)"); app.add_option("-u, --use", param.use_config,
app.add_option("-a, --append", param.appendValue, "添加服务器地址组(地址格式:127.0.0.1:9898:注释)"); "使用服务器地址组(值为使用--show中显示的序号)");
app.add_option("-a, --append", param.appendValue,
"添加服务器地址组(地址格式:127.0.0.1:9898:注释)");
app.add_flag("-s, --show", param.showValue, "查看服务器地址组"); app.add_flag("-s, --show", param.showValue, "查看服务器地址组");
app.add_option("-r, --remove", param.removeValue, "移除服务器地址组(值为使用--show中显示的序号)"); app.add_option("-r, --remove", param.removeValue,
app.add_flag("-d, --direct", param.direct_use, "添加服务器时直接使用此服务器。"); "移除服务器地址组(值为使用--show中显示的序号)");
app.add_flag("-l, --last", param.last_use, "直接使用之前最后一次使用的服务器。"); app.add_flag("-d, --direct", param.direct_use,
"添加服务器时直接使用此服务器。");
app.add_flag("-l, --last", param.last_use,
"直接使用之前最后一次使用的服务器。");
app.add_flag("-n, --null", param.null_use, "先运行在选择服务器。"); app.add_flag("-n, --null", param.null_use, "先运行在选择服务器。");
app.add_option("-c, --connect", param.connectValue, "直连服务器((地址格式:127.0.0.1:9898)。"); app.add_option("-c, --connect", param.connectValue,
"直连服务器((地址格式:127.0.0.1:9898)。");
if (argc == 1) { if (argc == 1) {
std::cout << app.help() << std::endl; std::cout << app.help() << std::endl;
return 0; return 0;
} }
// 这里的 CLI11_PARSE 在程序没有输入或者仅输入--help(-h)时,会直接返回,后面代码都不会执行。 // 这里的 CLI11_PARSE
// 在程序没有输入或者仅输入--help(-h)时,会直接返回,后面代码都不会执行。
// 当有自定义的参数被输入时,后面代码会执行。 // 当有自定义的参数被输入时,后面代码会执行。
try { try {
CLI11_PARSE(app, argc, argv); CLI11_PARSE(app, argc, argv);
@ -57,7 +61,8 @@ int parse_cmd(int argc, char** argv, CmdParam& param)
return 0; return 0;
} }
bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& port) bool select_server(const std::vector<TransmSet>& sets, std::string& ip,
long& port)
{ {
TLOGI("Please Select a Server:"); TLOGI("Please Select a Server:");
if (sets.empty()) { if (sets.empty()) {
@ -70,7 +75,8 @@ bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& po
if (server.comment.empty()) { if (server.comment.empty()) {
TLOGI("[{}] {}:{}", i + 1, server.ip, server.port); TLOGI("[{}] {}:{}", i + 1, server.ip, server.port);
} else { } else {
TLOGI("[{}] {}:{} ({})", i + 1, server.ip, server.port, server.comment); TLOGI("[{}] {}:{} ({})", i + 1, server.ip, server.port,
server.comment);
} }
} }
@ -86,8 +92,10 @@ bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& po
} }
// 检查输入是否为空或非数字 // 检查输入是否为空或非数字
if (input.empty() || !std::all_of(input.begin(), input.end(), ::isdigit)) { if (input.empty() ||
TLOGE("Invalid input '{}'. Please enter a valid number or 'exit'.", input); !std::all_of(input.begin(), input.end(), ::isdigit)) {
TLOGE("Invalid input '{}'. Please enter a valid number or 'exit'.",
input);
continue; continue;
} }
@ -96,7 +104,9 @@ bool select_server(const std::vector<TransmSet>& sets, std::string& ip, long& po
// 检查数字是否在有效范围内 // 检查数字是否在有效范围内
if (choice < 1 || choice > static_cast<int>(sets.size())) { if (choice < 1 || choice > static_cast<int>(sets.size())) {
TLOGE("Invalid choice '{}'. Please select a number between 1 and {}.", choice, sets.size()); TLOGE(
"Invalid choice '{}'. Please select a number between 1 and {}.",
choice, sets.size());
continue; continue;
} }
@ -119,7 +129,8 @@ bool exec_cmd(CmdParam& param, bool& run)
return false; return false;
} }
for (const auto& item : set) { for (const auto& item : set) {
TLOGI("{} => {}:{} {}", item.group, item.ip, item.port, item.comment); TLOGI("{} => {}:{} {}", item.group, item.ip, item.port,
item.comment);
} }
return true; return true;
} }
@ -132,7 +143,8 @@ bool exec_cmd(CmdParam& param, bool& run)
return false; return false;
} }
if (!param.appendValue.empty()) { if (!param.appendValue.empty()) {
std::regex pattern(R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)(?::(.*))?)"); std::regex pattern(
R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)(?::(.*))?)");
std::smatch matches; std::smatch matches;
std::string ip, port, comment; std::string ip, port, comment;
if (std::regex_match(param.appendValue, matches, pattern)) { if (std::regex_match(param.appendValue, matches, pattern)) {
@ -151,7 +163,8 @@ bool exec_cmd(CmdParam& param, bool& run)
} }
if (!param.removeValue.empty()) { if (!param.removeValue.empty()) {
if (!g_Config->remove_ini(std::stol(param.removeValue))) { if (!g_Config->remove_ini(std::stol(param.removeValue))) {
TLOGW("remove config num=[{}] failed, please check!", param.removeValue); TLOGW("remove config num=[{}] failed, please check!",
param.removeValue);
return false; return false;
} }
TLOGI("remove config num=[{}] success!", param.removeValue); TLOGI("remove config num=[{}] success!", param.removeValue);
@ -206,7 +219,8 @@ int main(int argc, char* argv[])
std::regex pattern(R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+))"); std::regex pattern(R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+))");
std::smatch matches; std::smatch matches;
if (std::regex_match(param.connectValue, matches, pattern) && matches.size() == 3) { if (std::regex_match(param.connectValue, matches, pattern) &&
matches.size() == 3) {
ip = matches[1].str(); ip = matches[1].str();
port = std::stol(matches[2].str()); port = std::stol(matches[2].str());
run = true; run = true;
@ -250,7 +264,8 @@ int main(int argc, char* argv[])
} }
g_Config->save_last_use(ip, port); g_Config->save_last_use(ip, port);
} }
TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__, VERSION_GIT_COMMIT, VERSION_GIT_BRANCH); TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__,
VERSION_GIT_COMMIT, VERSION_GIT_BRANCH);
TLOGI("use ip => [{}], port => [{}]", ip, port); TLOGI("use ip => [{}], port => [{}]", ip, port);
std::shared_ptr<TransmClient> client = std::make_shared<TransmClient>(); std::shared_ptr<TransmClient> client = std::make_shared<TransmClient>();
client->run(ip, std::to_string(port), g_Config->get_config_dir()); client->run(ip, std::to_string(port), g_Config->get_config_dir());

View File

@ -1,6 +1,3 @@
set(MBOOST_INCLUDE_DIR "C:/boost/include/boost-1_83")
set(MBOOST_LIB_DIR "C:/boost/lib")
set(MBOOST_LIBS "boost_filesystem-mgw7-mt-x32-1_83")
get_filename_component(CXX_COMPILER_PATH ${CMAKE_CXX_COMPILER} DIRECTORY) get_filename_component(CXX_COMPILER_PATH ${CMAKE_CXX_COMPILER} DIRECTORY)
set(MINGW32_DLLS set(MINGW32_DLLS
"${CXX_COMPILER_PATH}/libgcc_s_dw2-1.dll" "${CXX_COMPILER_PATH}/libgcc_s_dw2-1.dll"

@ -1 +1 @@
Subproject commit b9e7bdb7349cc0c469800e42b309676fb5495be8 Subproject commit 1d84054da9ec3a70ae1311d6166a9404a10a356c

@ -1 +1 @@
Subproject commit 4b6612cc63f21b4d092a0b5731ceb7f817f20d23 Subproject commit 1a35e4371945b7c439a95a3e42612e9870e03e65

View File

@ -1,7 +1,7 @@
@echo off @echo off
cmake -Bxpbuild -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DXP_SYSTEM=ON -DUSE_BOOST=ON cmake -BMinGWBuild -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
cd xpbuild cd MinGWBuild
cpack cpack
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
echo Error: cmake build failed. echo Error: cmake build failed.

2
ofen

@ -1 +1 @@
Subproject commit fbc26d565f7b73418dd9bfaee3fc67b77a56daba Subproject commit e1624c71451febf956a98bc692c0e886366f4c34

View File

@ -6,17 +6,9 @@ set(CMAKE_CXX_STANDARD 17)
if (MSVC) if (MSVC)
add_compile_options(/source-charset:utf-8) add_compile_options(/source-charset:utf-8)
endif() endif()
if(DEFINED USE_BOOST)
message(STATUS "tss use boost lib.")
include_directories(${MBOOST_INCLUDE_DIR})
endif()
add_executable(tss main.cpp server.h server.cpp) add_executable(tss main.cpp server.h server.cpp)
target_link_libraries(tss PRIVATE trans_net trans_util) target_link_libraries(tss PRIVATE trans_net trans_util)
if(DEFINED USE_BOOST)
target_link_directories(tss PRIVATE ${MBOOST_LIB_DIR})
target_link_libraries(tss PRIVATE ${MBOOST_LIBS})
endif()
if (UNIX) if (UNIX)
target_link_libraries(tss PRIVATE pthread) target_link_libraries(tss PRIVATE pthread)
endif() endif()

View File

@ -3,7 +3,9 @@
#include "server.h" #include "server.h"
#include "version.h" #include "version.h"
#include <filesystem>
#include <of_path.h> #include <of_path.h>
namespace fs = std::filesystem;
#ifdef _WIN32 #ifdef _WIN32
#include <fcntl.h> #include <fcntl.h>
@ -18,14 +20,6 @@
#include <crashelper.h> #include <crashelper.h>
#endif #endif
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
void msignal_handler(int signal) void msignal_handler(int signal)
{ {
fc_recovery_color(); fc_recovery_color();
@ -41,6 +35,8 @@ int main(int argc, char* argv[])
backward::SetDumpLogSavePath(err); backward::SetDumpLogSavePath(err);
CRASHELPER_MARK_ENTRY(); CRASHELPER_MARK_ENTRY();
sh.register_user_sig_handler([](int sig) { msignal_handler(sig); }); sh.register_user_sig_handler([](int sig) { msignal_handler(sig); });
#else
signal(SIGINT, msignal_handler);
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -56,7 +52,8 @@ int main(int argc, char* argv[])
delete p; delete p;
}); });
TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__, VERSION_GIT_COMMIT, VERSION_GIT_BRANCH); TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__,
VERSION_GIT_COMMIT, VERSION_GIT_BRANCH);
int port = 9898; int port = 9898;
if (argc < 2) { if (argc < 2) {
TLOGI("Use Default Port:{}", port); TLOGI("Use Default Port:{}", port);

View File

@ -53,34 +53,42 @@ bool base_connect()
} }
server_th = std::thread(server_run); server_th = std::thread(server_run);
if (value_wait<bool>([]() -> bool { return server_suc; }, true, std::equal_to<bool>(), max_wait, if (value_wait<bool>([]() -> bool { return server_suc; }, true,
std::equal_to<bool>(), max_wait,
wait_interval) == false) { wait_interval) == false) {
return false; return false;
} }
clientA = std::make_shared<TransmClient>(); clientA = std::make_shared<TransmClient>();
if (clientA->connect_for_test(ip, std::to_string(port), config->get_config_dir()) == false) { if (clientA->connect_for_test(ip, std::to_string(port),
config->get_config_dir()) == false) {
return false; return false;
} }
clientB = std::make_shared<TransmClient>(); clientB = std::make_shared<TransmClient>();
if (clientB->connect_for_test(ip, std::to_string(port), config->get_config_dir()) == false) { if (clientB->connect_for_test(ip, std::to_string(port),
config->get_config_dir()) == false) {
return false; return false;
} }
if (value_wait<std::string>([]() -> std::string { return clientA->test_get_own_id(); }, std::string(), if (value_wait<std::string>(
std::not_equal_to<std::string>(), max_wait, wait_interval) == false) { []() -> std::string { return clientA->test_get_own_id(); },
std::string(), std::not_equal_to<std::string>(), max_wait,
wait_interval) == false) {
return false; return false;
} }
if (value_wait<std::string>([]() -> std::string { return clientB->test_get_own_id(); }, std::string(), if (value_wait<std::string>(
std::not_equal_to<std::string>(), max_wait, wait_interval) == false) { []() -> std::string { return clientB->test_get_own_id(); },
std::string(), std::not_equal_to<std::string>(), max_wait,
wait_interval) == false) {
return false; return false;
} }
str_id_a = clientA->test_get_own_id(); str_id_a = clientA->test_get_own_id();
std::cout << "clientA id: " << str_id_a << std::endl; std::cout << "clientA id: " << str_id_a << std::endl;
if (value_wait<int>([]() -> int { return clientB->test_index_by_id(str_id_a); }, -1, if (value_wait<int>(
[]() -> int { return clientB->test_index_by_id(str_id_a); }, -1,
std::not_equal_to<int>(), max_wait, wait_interval) == false) { std::not_equal_to<int>(), max_wait, wait_interval) == false) {
return false; return false;
} }
@ -173,9 +181,12 @@ bool test_up_task(bool encrypt)
} }
if (value_wait<TransmClient::TaskState>( if (value_wait<TransmClient::TaskState>(
[&]() -> TransmClient::TaskState { return clientB->get_task_state(); }, [&]() -> TransmClient::TaskState {
TransmClient::TaskState::TASK_STATE_IDLE, std::not_equal_to<TransmClient::TaskState>(), return clientB->get_task_state();
max_wait * 2, wait_interval) == false) { },
TransmClient::TaskState::TASK_STATE_IDLE,
std::not_equal_to<TransmClient::TaskState>(), max_wait * 2,
wait_interval) == false) {
return false; return false;
} }
@ -192,7 +203,8 @@ bool test_up_task(bool encrypt)
return false; return false;
} }
std::cout << "****** up task done encrypt:" << encrypt << " ******" << std::endl; std::cout << "****** up task done encrypt:" << encrypt << " ******"
<< std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
return true; return true;
} }
@ -213,7 +225,8 @@ bool random_ralated_files()
fs::remove(test_task_file); fs::remove(test_task_file);
} }
std::ofstream ofs(test_task_file); std::ofstream ofs(test_task_file);
ofs << "${CURRENT}/" << test_filea << "|" << test_sub_dir + "/" << std::endl; ofs << "${CURRENT}/" << test_filea << "|" << test_sub_dir + "/"
<< std::endl;
ofs << test_fileb << "|" << test_sub_dir + "/" << std::endl; ofs << test_fileb << "|" << test_sub_dir + "/" << std::endl;
ofs.close(); ofs.close();
return true; return true;

View File

@ -54,7 +54,8 @@ bool test_speed(SpeedRet& ret)
hash(key.c_str(), ik); hash(key.c_str(), ik);
fs::path decrypted_path = fs::path(test_file).replace_filename( fs::path decrypted_path = fs::path(test_file).replace_filename(
fs::path(test_file).stem().string() + "_decrypted" + fs::path(test_file).extension().string()); fs::path(test_file).stem().string() + "_decrypted" +
fs::path(test_file).extension().string());
std::ofstream decrypted_file(decrypted_path, std::ios::binary); std::ofstream decrypted_file(decrypted_path, std::ios::binary);
if (!decrypted_file) { if (!decrypted_file) {
@ -70,7 +71,8 @@ bool test_speed(SpeedRet& ret)
// 测试数据缓冲区(额外预留16字节空间) // 测试数据缓冲区(额外预留16字节空间)
std::vector<uint8_t> original_block(BLOCK_SIZE); std::vector<uint8_t> original_block(BLOCK_SIZE);
std::vector<uint8_t> processing_block(BLOCK_SIZE + IV_SIZE); // 加密/解密处理缓冲区 std::vector<uint8_t> processing_block(BLOCK_SIZE +
IV_SIZE); // 加密/解密处理缓冲区
size_t total_bytes = 0; size_t total_bytes = 0;
size_t blocks_processed = 0; size_t blocks_processed = 0;
@ -80,39 +82,49 @@ bool test_speed(SpeedRet& ret)
auto total_decrypt_time = std::chrono::microseconds(0); auto total_decrypt_time = std::chrono::microseconds(0);
while (in_file) { while (in_file) {
in_file.read(reinterpret_cast<char*>(original_block.data()), BLOCK_SIZE - IV_SIZE); in_file.read(reinterpret_cast<char*>(original_block.data()),
BLOCK_SIZE - IV_SIZE);
size_t bytes_read = in_file.gcount(); size_t bytes_read = in_file.gcount();
if (bytes_read == 0) if (bytes_read == 0)
break; break;
memcpy(processing_block.data() + IV_SIZE, original_block.data(), bytes_read); memcpy(processing_block.data() + IV_SIZE, original_block.data(),
bytes_read);
auto start_encrypt = std::chrono::high_resolution_clock::now(); auto start_encrypt = std::chrono::high_resolution_clock::now();
if (!encrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) { if (!encrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) {
std::cerr << "Encryption failed at block " << blocks_processed << std::endl; std::cerr << "Encryption failed at block " << blocks_processed
<< std::endl;
verification_passed = false; verification_passed = false;
break; break;
} }
auto end_encrypt = std::chrono::high_resolution_clock::now(); auto end_encrypt = std::chrono::high_resolution_clock::now();
total_encrypt_time += total_encrypt_time +=
std::chrono::duration_cast<std::chrono::microseconds>(end_encrypt - start_encrypt); std::chrono::duration_cast<std::chrono::microseconds>(
end_encrypt - start_encrypt);
auto start_decrypt = std::chrono::high_resolution_clock::now(); auto start_decrypt = std::chrono::high_resolution_clock::now();
if (!decrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) { if (!decrypt(ik, processing_block.data(), bytes_read + IV_SIZE)) {
std::cerr << "Decryption failed at block " << blocks_processed << std::endl; std::cerr << "Decryption failed at block " << blocks_processed
<< std::endl;
verification_passed = false; verification_passed = false;
break; break;
} }
auto end_decrypt = std::chrono::high_resolution_clock::now(); auto end_decrypt = std::chrono::high_resolution_clock::now();
total_decrypt_time += total_decrypt_time +=
std::chrono::duration_cast<std::chrono::microseconds>(end_decrypt - start_decrypt); std::chrono::duration_cast<std::chrono::microseconds>(
end_decrypt - start_decrypt);
if (memcmp(original_block.data(), processing_block.data() + IV_SIZE, bytes_read) != 0) { if (memcmp(original_block.data(), processing_block.data() + IV_SIZE,
std::cerr << "Data mismatch at block " << blocks_processed << std::endl; bytes_read) != 0) {
std::cerr << "Data mismatch at block " << blocks_processed
<< std::endl;
verification_passed = false; verification_passed = false;
break; break;
} }
decrypted_file.write(reinterpret_cast<const char*>(processing_block.data() + IV_SIZE), bytes_read); decrypted_file.write(
reinterpret_cast<const char*>(processing_block.data() + IV_SIZE),
bytes_read);
total_bytes += bytes_read; total_bytes += bytes_read;
blocks_processed++; blocks_processed++;
} }
@ -129,10 +141,10 @@ bool test_speed(SpeedRet& ret)
#endif #endif
// 计算吞吐量(只计算有效数据部分) // 计算吞吐量(只计算有效数据部分)
double encrypt_throughput = double encrypt_throughput = (double)total_bytes / (1024 * 1024) /
(double)total_bytes / (1024 * 1024) / (total_encrypt_time.count() / 1000000.0); (total_encrypt_time.count() / 1000000.0);
double decrypt_throughput = double decrypt_throughput = (double)total_bytes / (1024 * 1024) /
(double)total_bytes / (1024 * 1024) / (total_decrypt_time.count() / 1000000.0); (total_decrypt_time.count() / 1000000.0);
ret.encry_speed = encrypt_throughput; ret.encry_speed = encrypt_throughput;
ret.decry_speed = decrypt_throughput; ret.decry_speed = decrypt_throughput;

View File

@ -1,19 +1,13 @@
#ifndef ASSISTANT_H #ifndef ASSISTANT_H
#define ASSISTANT_H #define ASSISTANT_H
#include <filesystem>
#include <fstream> #include <fstream>
#include <functional> #include <functional>
#include <random> #include <random>
#include <string> #include <string>
#include <thread> #include <thread>
#ifdef USE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
#endif
/** /**
* @brief * @brief
@ -40,8 +34,9 @@ bool random_file(const std::string& file, size_t size);
* @return false * @return false
*/ */
template <typename T, typename Compare = std::equal_to<T>> template <typename T, typename Compare = std::equal_to<T>>
bool value_wait(const std::function<T()>& value_ref, const T& expected, Compare comparator = Compare(), bool value_wait(const std::function<T()>& value_ref, const T& expected,
unsigned long timeout_ms = 0, unsigned long interval_ms = 100) Compare comparator = Compare(), unsigned long timeout_ms = 0,
unsigned long interval_ms = 100)
{ {
auto start = std::chrono::steady_clock::now(); auto start = std::chrono::steady_clock::now();
@ -53,7 +48,8 @@ bool value_wait(const std::function<T()>& value_ref, const T& expected, Compare
} }
if (timeout_ms > 0) { if (timeout_ms > 0) {
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>( auto elapsed =
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start) std::chrono::steady_clock::now() - start)
.count(); .count();
@ -103,7 +99,8 @@ private:
}; };
#define _SCOPE_EXIT_CONCAT(a, b) a##b #define _SCOPE_EXIT_CONCAT(a, b) a##b
#define _MAKE_ON_SCOPE_EXIT(line) ScopeExit _SCOPE_EXIT_CONCAT(exit_defer_, line) = [&]() #define _MAKE_ON_SCOPE_EXIT(line) \
ScopeExit _SCOPE_EXIT_CONCAT(exit_defer_, line) = [&]()
#define ON_SCOPE_EXIT _MAKE_ON_SCOPE_EXIT(__LINE__) #define ON_SCOPE_EXIT _MAKE_ON_SCOPE_EXIT(__LINE__)
#endif // ASSISTANT_H #endif // ASSISTANT_H

View File

@ -1,10 +1,12 @@
/* /*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode. This is an implementation of the AES algorithm, specifically ECB, CTR and CBC
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256. mode. Block size can be chosen in aes.h - available choices are AES128, AES192,
AES256.
The implementation is verified against the test vectors in: The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED National Institute of Standards and Technology Special Publication 800-38A
2001 ED
ECB-AES128 ECB-AES128
---------- ----------
@ -42,7 +44,8 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
/*****************************************************************************/ /*****************************************************************************/
/* Defines: */ /* Defines: */
/*****************************************************************************/ /*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4 // The number of columns comprising a state in AES. This is a constant in AES.
// Value=4
#define Nb 4 #define Nb 4
#if defined(AES256) && (AES256 == 1) #if defined(AES256) && (AES256 == 1)
@ -58,7 +61,8 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
// jcallan@github points out that declaring Multiply as a function // jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler. // reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3 // See this link for more information:
// https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION #ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0 #define MULTIPLY_AS_A_FUNCTION 0
#endif #endif
@ -69,59 +73,77 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
// state - array holding the intermediate results during decryption. // state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4]; typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM // The lookup-tables are marked const so they can be placed in read-only storage
// The numbers below can be computed dynamically trading ROM for RAM - // instead of RAM The numbers below can be computed dynamically trading ROM for
// This can be useful in (embedded) bootloader applications, where ROM is often limited. // RAM - This can be useful in (embedded) bootloader applications, where ROM is
// often limited.
static const uint8_t sbox[256] = { static const uint8_t sbox[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F // 0 1 2 3 4 5 6 7 8 9 A B C
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // D E F
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16};
static const uint8_t rsbox[256] = { static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0c, 0x7d};
// The round constant word array, Rcon[i], contains the values given by // The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) // x to the power (i-1) being powers of x (x is denoted as {02}) in the field
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; // GF(2^8)
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36};
/* /*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12), * Jordan Goulder points out in PR #12
* that you can remove most of the elements in the Rcon array, because they are unused. * (https://github.com/kokke/tiny-AES-C/pull/12), that you can remove most of
* the elements in the Rcon array, because they are unused.
* *
* From Wikipedia's article on the Rijndael key schedule @ * From Wikipedia's article on the Rijndael key schedule @
* https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon * https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
* *
* "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys * "Only the first some of these constants are actually used – up to rcon[10]
* are needed), up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm." * for AES-128 (as 11 round keys are needed), up to rcon[8] for AES-192, up to
* rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/ */
/*****************************************************************************/ /*****************************************************************************/
@ -142,7 +164,8 @@ static uint8_t getSBoxInvert(uint8_t num)
*/ */
#define getSBoxInvert(num) (rsbox[(num)]) #define getSBoxInvert(num) (rsbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. // This function produces Nb(Nr+1) round keys. The round keys are used in each
// round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key) static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{ {
unsigned i, j, k; unsigned i, j, k;
@ -180,7 +203,8 @@ static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
} }
// SubWord() is a function that takes a four-byte input word and // SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word. // applies the S-box to each of the four bytes to produce an output
// word.
// Function Subword() // Function Subword()
{ {
@ -312,27 +336,33 @@ static void MixColumns(state_t* state)
} }
// Multiply is used to multiply numbers in the field GF(2^8) // Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary // Note: The last call to xtime() is unneeded, but often ends up generating a
// The compiler seems to be able to vectorize the operation better this way. // smaller binary
// See https://github.com/kokke/tiny-AES-c/pull/34 // The compiler seems to be able to vectorize the operation better this
// way. See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION #if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y) static uint8_t Multiply(uint8_t x, uint8_t y)
{ {
return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ ((y >> 2 & 1) * xtime(xtime(x))) ^ return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^
((y >> 2 & 1) * xtime(xtime(x))) ^
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^
((y >> 4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */ ((y >> 4 & 1) *
xtime(xtime(xtime(
xtime(x)))))); /* this last call to xtime() can be omitted */
} }
#else #else
#define Multiply(x, y) \ #define Multiply(x, y) \
(((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ ((y >> 2 & 1) * xtime(xtime(x))) ^ \ (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ \
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x)))))) ((y >> 2 & 1) * xtime(xtime(x))) ^ \
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))))
#endif #endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// MixColumns function mixes the columns of the state matrix. // MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced. // The method used to multiply may be difficult to understand for the
// Please use the references to gain more information. // inexperienced. Please use the references to gain more information.
static void InvMixColumns(state_t* state) static void InvMixColumns(state_t* state)
{ {
int i; int i;
@ -343,10 +373,14 @@ static void InvMixColumns(state_t* state)
c = (*state)[i][2]; c = (*state)[i][2];
d = (*state)[i][3]; d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^
Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^
Multiply(c, 0x09) ^ Multiply(d, 0x0e);
} }
} }
@ -449,13 +483,15 @@ static void InvCipher(state_t* state, uint8_t* RoundKey)
void AES_ECB_encrypt(struct AES_ctx* ctx, uint8_t* buf) void AES_ECB_encrypt(struct AES_ctx* ctx, uint8_t* buf)
{ {
// The next function call encrypts the PlainText with the Key using AES algorithm. // The next function call encrypts the PlainText with the Key using AES
// algorithm.
Cipher((state_t*)buf, ctx->RoundKey); Cipher((state_t*)buf, ctx->RoundKey);
} }
void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf) void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf)
{ {
// The next function call decrypts the PlainText with the Key using AES algorithm. // The next function call decrypts the PlainText with the Key using AES
// algorithm.
InvCipher((state_t*)buf, ctx->RoundKey); InvCipher((state_t*)buf, ctx->RoundKey);
} }
@ -466,7 +502,8 @@ void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf)
static void XorWithIv(uint8_t* buf, uint8_t* Iv) static void XorWithIv(uint8_t* buf, uint8_t* Iv)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size for (i = 0; i < AES_BLOCKLEN;
++i) // The block in AES is always 128bit no matter the key size
{ {
buf[i] ^= Iv[i]; buf[i] ^= Iv[i];
} }
@ -504,8 +541,8 @@ void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
#if defined(CTR) && (CTR == 1) #if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be /* Symmetrical operation: same function for encrypting as for decrypting. Note
* reused with the same key */ * any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length) void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{ {
uint8_t buffer[AES_BLOCKLEN]; uint8_t buffer[AES_BLOCKLEN];

View File

@ -7,10 +7,11 @@
// //
// CBC enables AES encryption in CBC-mode of operation. // CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode. // CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously. // ECB enables the basic ECB 16-byte block algorithm. All can be enabled
// simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time. // The #ifndef-guard allows it to be configured before #include'ing or at
// #ifndef CBC // compile time. #ifndef CBC
// #define CBC 1 // #define CBC 1
// #endif // #endif
@ -53,7 +54,8 @@ struct AES_ctx {
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key); void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv); void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key,
const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv); void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif #endif
@ -68,8 +70,9 @@ void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf);
#if defined(CBC) && (CBC == 1) #if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN; // buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme // Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv() // padding scheme NOTES: you need to set IV in ctx via AES_init_ctx_iv() or
// AES_ctx_set_iv()
// no IV should ever be reused with the same key // no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length); void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length); void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
@ -79,8 +82,9 @@ void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#if defined(CTR) && (CTR == 1) #if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting. // Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output // IV is incremented for every block, and used after encryption as
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme // XOR-compliment for output Suggesting
// https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv() // NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key // no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length); void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);

View File

@ -48,7 +48,8 @@ CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer)
int32_t len{}; int32_t len{};
std::memcpy(&type, buffer.get_data() + find + 2, sizeof(type)); std::memcpy(&type, buffer.get_data() + find + 2, sizeof(type));
std::memcpy(&mark, buffer.get_data() + find + 2 + 2, sizeof(mark)); std::memcpy(&mark, buffer.get_data() + find + 2 + 2, sizeof(mark));
std::memcpy(&len, buffer.get_data() + find + 2 + 2 + 1 + 32 + 32, sizeof(len)); std::memcpy(&len, buffer.get_data() + find + 2 + 2 + 1 + 32 + 32,
sizeof(len));
int32_t tail_index = find + 2 + 2 + 1 + 32 + 32 + 4 + len; int32_t tail_index = find + 2 + 2 + 1 + 32 + 32 + 4 + len;
if (buffer.get_len() - 2 < tail_index || len < 0) { if (buffer.get_len() - 2 < tail_index || len < 0) {
@ -67,7 +68,8 @@ CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer)
result->mark_ = mark; result->mark_ = mark;
result->type_ = static_cast<FrameType>(type); result->type_ = static_cast<FrameType>(type);
if (len > 0) { if (len > 0) {
std::memcpy(result->data_, buffer.get_data() + find + 2 + 2 + 1 + 4 + 32 + 32, len); std::memcpy(result->data_,
buffer.get_data() + find + 2 + 2 + 1 + 4 + 32 + 32, len);
} }
buffer.remove_of(0, tail_index + 2); buffer.remove_of(0, tail_index + 2);
return result; return result;
@ -93,7 +95,8 @@ bool CTransProtocal::pack(CFrameBuffer* buf, char** out_buf, int& len)
std::memcpy(*out_buf + 2 + 2 + 1, buf->fid_.data(), buf->fid_.size()); std::memcpy(*out_buf + 2 + 2 + 1, buf->fid_.data(), buf->fid_.size());
} }
if (!buf->tid_.empty()) { if (!buf->tid_.empty()) {
std::memcpy(*out_buf + 2 + 2 + 1 + 32, buf->tid_.data(), buf->tid_.size()); std::memcpy(*out_buf + 2 + 2 + 1 + 32, buf->tid_.data(),
buf->tid_.size());
} }
std::memcpy(*out_buf + 2 + 2 + 1 + 32 + 32, &buf->len_, 4); std::memcpy(*out_buf + 2 + 2 + 1 + 32 + 32, &buf->len_, 4);
if (buf->data_ != nullptr) { if (buf->data_ != nullptr) {
@ -142,13 +145,15 @@ void serialize(CMessageInfo& msg_info, char** out_buf, int& len, bool reuse_mem)
info.str = localtou8(info.str); info.str = localtou8(info.str);
// 计算总长度 // 计算总长度
len = sizeof(int) * 4 + info.id.size() + info.uuid.size() + info.str.size() + info.data.size() + kz + 1; len = sizeof(int) * 4 + info.id.size() + info.uuid.size() +
info.str.size() + info.data.size() + kz + 1;
// 《这里为了效率》, // 《这里为了效率》,
// 认为如果 *out_buf 不为空,则直接使用,且长度符合要求 // 认为如果 *out_buf 不为空,则直接使用,且长度符合要求
// 调用方负责确保内存够用性(len <= 可用最大空间长度)和内存可用性。 // 调用方负责确保内存够用性(len <= 可用最大空间长度)和内存可用性。
// 即,如果调用方及高频率调用 serialize, 且每次 len <= 已分配空间就复用内存,完了再释放。 // 即,如果调用方及高频率调用 serialize, 且每次 len <=
// 低频率或者 len 不固定时,每次都释放内存,并置 nullptr。 // 已分配空间就复用内存,完了再释放。 低频率或者 len
// 不固定时,每次都释放内存,并置 nullptr。
if (*out_buf) { if (*out_buf) {
if (!reuse_mem) { if (!reuse_mem) {
delete[] *out_buf; delete[] *out_buf;
@ -327,7 +332,8 @@ void rdm(uint8_t* o, size_t size)
// std::mt19937 gen(rd()); // std::mt19937 gen(rd());
std::mt19937_64 gen(rd()); std::mt19937_64 gen(rd());
std::uniform_int_distribution<int> dist(0, 255); std::uniform_int_distribution<int> dist(0, 255);
std::generate(o, o + size, [&]() { return static_cast<uint8_t>(dist(gen)); }); std::generate(o, o + size,
[&]() { return static_cast<uint8_t>(dist(gen)); });
} }
bool encrypt(const uint8_t* k, uint8_t* m, size_t len) bool encrypt(const uint8_t* k, uint8_t* m, size_t len)

View File

@ -53,7 +53,8 @@ struct CMessageInfo {
std::string data; std::string data;
}; };
void serialize(CMessageInfo& msg_info, char** out_buf, int& len, bool reuse_mem = false); void serialize(CMessageInfo& msg_info, char** out_buf, int& len,
bool reuse_mem = false);
bool deserialize(char* data, int len, CMessageInfo& msg_info); bool deserialize(char* data, int len, CMessageInfo& msg_info);
std::string u8tolocal(const std::string& str); std::string u8tolocal(const std::string& str);
std::string localtou8(const std::string& str); std::string localtou8(const std::string& str);
@ -110,39 +111,54 @@ inline std::string now_str()
{ {
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
auto time_t_now = std::chrono::system_clock::to_time_t(now); auto time_t_now = std::chrono::system_clock::to_time_t(now);
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) %
1000;
std::ostringstream timestamp; std::ostringstream timestamp;
timestamp << std::put_time(std::localtime(&time_t_now), "[%m-%d %H:%M:%S") << "." << std::setfill('0') << std::setw(3) timestamp << std::put_time(std::localtime(&time_t_now), "[%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3)
<< milliseconds.count() << "] "; << milliseconds.count() << "] ";
return timestamp.str(); return timestamp.str();
} }
template <typename... Args> void TLOGI(const std::string& format, Args&&... args) template <typename... Args>
void TLOGI(const std::string& format, Args&&... args)
{ {
fc_lock_print(); fc_lock_print();
std::cout << ConsoleColor::Green << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl; std::cout << ConsoleColor::Green
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print(); fc_unlock_print();
} }
template <typename... Args> void TLOGW(const std::string& format, Args&&... args) template <typename... Args>
void TLOGW(const std::string& format, Args&&... args)
{ {
fc_lock_print(); fc_lock_print();
std::cout << ConsoleColor::Yellow << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl; std::cout << ConsoleColor::Yellow
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print(); fc_unlock_print();
} }
template <typename... Args> void TLOGE(const std::string& format, Args&&... args) template <typename... Args>
void TLOGE(const std::string& format, Args&&... args)
{ {
fc_lock_print(); fc_lock_print();
std::cout << ConsoleColor::Red << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl; std::cout << ConsoleColor::Red
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print(); fc_unlock_print();
} }
template <typename... Args> void TLOGD(const std::string& format, Args&&... args) template <typename... Args>
void TLOGD(const std::string& format, Args&&... args)
{ {
fc_lock_print(); fc_lock_print();
std::cout << ConsoleColor::Cyan << fmt::format(now_str() + format, std::forward<Args>(args)...) << std::endl; std::cout << ConsoleColor::Cyan
<< fmt::format(now_str() + format, std::forward<Args>(args)...)
<< std::endl;
fc_unlock_print(); fc_unlock_print();
} }