正文
將字串轉換成等效int陣列
std::vector<uint32_t> convert_wstring_to_int_array(const wchar_t *str) {
std::vector<uint32_t> vec;
for (size_t i = 0; i < wcslen(str); i += 2) {
uint32_t val = (uint32_t)str[i] << 16 & 0xff0000;
if (i < wcslen(str) - 1) {
val |= (uint32_t)str[i + 1] & 0xff;
}
vec.push_back(val);
}
if (vec.back() & 0xffff) {
vec.push_back(0);
}
return vec;
}
std::vector<uint32_t> convert_string_to_int_array(const char *str) {
std::vector<uint32_t> vec;
for (int i = 0; i < int(strlen(str)); i += 4) {
uint32_t val = (uint32_t)str[i] << 24 & 0xff000000;
if (i < int(strlen(str)) - 1) {
val |= (uint32_t)str[i + 1] << 16 & 0xff0000;
}
if (i < int(strlen(str)) - 2) {
val |= (uint32_t)str[i + 2] << 8 & 0xff00;
}
if (i < int(strlen(str)) - 3) {
val |= (uint32_t)str[i + 3] & 0xff;
}
vec.push_back(val);
}
return vec;
}
編譯時xor混淆字串
#pragma once
namespace zzz {
#define XSTR_SEED \
((__TIME__[7] - '0') * 1ull + (__TIME__[6] - '0') * 10ull + (__TIME__[4] - '0') * 60ull + \
(__TIME__[3] - '0') * 600ull + (__TIME__[1] - '0') * 3600ull + (__TIME__[0] - '0') * 36000ull)
constexpr unsigned long long linear_congruent_generator(unsigned rounds) {
return 1013904223ull +
(1664525ull * ((rounds > 0) ? linear_congruent_generator(rounds - 1) : (XSTR_SEED))) % 0xFFFFFFFF;
}
#define Random() linear_congruent_generator(10)
#define XSTR_RANDOM_NUMBER(Min, Max) (Min + (Random() % (Max - Min + 1)))
// FIXME: Why use XSTR_RANDOM_NUMBER(0, 0xFF) will cause undefined behavior??
constexpr const unsigned long long XORKEY = 0x56; // XSTR_RANDOM_NUMBER(0, 0xFF);
template <typename Char>
constexpr Char encrypt_character(const Char character, int index) {
return character ^ (static_cast<Char>(XORKEY) + index);
}
template <unsigned size, typename Char>
class Xor_string {
public:
const unsigned _nb_chars = (size - 1);
Char _string[size];
// if every goes alright this constructor should be executed at compile time
inline constexpr Xor_string(const Char* string) : _string{} {
for (unsigned i = 0u; i < size; ++i) _string[i] = encrypt_character<Char>(string[i], i);
}
// This is executed at runtime.
// HACK: although decrypt() is const we modify '_string' in place
const Char* decrypt() const {
Char* string = const_cast<Char*>(_string);
for (unsigned t = 0; t < _nb_chars; t++) {
string[t] ^= (static_cast<Char>(XORKEY) + t);
}
string[_nb_chars] = '\0';
return string;
}
};
} // namespace zzz
#define XorS(name, my_string) \
constexpr zzz::Xor_string<(sizeof(my_string) / sizeof(char)), char> name(my_string)
// Because of a limitation/bug in msvc 2017 we need to declare zzz::Xor_string() as a constexpr
// otherwise the constructor is not evaluated at compile time. The lambda function is here to allow this declaration
// inside the macro because there is no such thing as casting to 'constexpr' (and casting to const does not solve this
// bug).
#define XorString(my_string) \
[] { \
constexpr zzz::Xor_string<(sizeof(my_string) / sizeof(char)), char> expr(my_string); \
return expr; \
}() \
.decrypt()
#define XorWS(name, my_string) \
constexpr zzz::Xor_string<(sizeof(my_string) / sizeof(wchar_t)), wchar_t> name(my_string)
#define XorWideString(my_string) \
[] { \
constexpr zzz::Xor_string<(sizeof(my_string) / sizeof(wchar_t)), wchar_t> expr(my_string); \
return expr; \
}() \
.decrypt()
// Crypt normal string char*
#define xorstr(string) XorString(string)
// crypt wide characters
#define xorstrw(string) XorWideString(string)