I'm trying to use the following XORString template/macro to encrypt string literals at compile time:
#pragma once
#include <string>
namespace utils {
template <int X> struct EnsureCompileTime {
enum : int {
Value = X
};
};
//Use Compile-Time as seed
#define compile_seed ( (__TIME__[7] - '0') * 1 + (__TIME__[6] - '0') * 10 + \
(__TIME__[4] - '0') * 60 + (__TIME__[3] - '0') * 600 + \
(__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000 )
constexpr int LinearCongruentGenerator(int Rounds) {
return 1013904223 + 1664525 * ((Rounds > 0) ? LinearCongruentGenerator(Rounds - 1) : compile_seed & 0xFFFFFFFF);
}
#define Random() EnsureCompileTime<LinearCongruentGenerator(10)>::Value //10 Rounds
#define RandomNumber(Min, Max) (Min + (Random() % (Max - Min + 1)))
template <int... Pack> struct IndexList {};
template <typename IndexList, int Right> struct Append;
template <int... Left, int Right> struct Append<IndexList<Left...>, Right> {
typedef IndexList<Left..., Right> Result;
};
template <int N> struct ConstructIndexList {
typedef typename Append<typename ConstructIndexList<N - 1>::Result, N - 1>::Result Result;
};
template <> struct ConstructIndexList<0> {
typedef IndexList<> Result;
};
template <typename Char, typename IndexList> class XorStringT;
template <typename Char, int... Index> class XorStringT<Char, IndexList<Index...> > {
private:
Char Value[sizeof...(Index)+1];
static const Char XORKEY = static_cast<Char>(RandomNumber(0, 0xFFFF));
template <typename Char>
constexpr Char EncryptCharacterT(const Char Character, int Index) {
return Character ^ (XORKEY + Index);
}
public:
__forceinline constexpr XorStringT(const Char* const String)
: Value{ EncryptCharacterT(String[Index], Index)... } {}
const Char *decrypt() {
for (int t = 0; t < sizeof...(Index); t++) {
Value[t] = Value[t] ^ (XORKEY + t);
}
Value[sizeof...(Index)] = static_cast<Char>(0);
return Value;
}
const Char *get() {
return Value;
}
};
#define XORSTR( String ) ( utils::XorStringT<char, utils::ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )
}
The code is not mine, and I know very little about c++ templates or metaprogramming. The code works as intended on small strings (<250 characters), however, I need to get it working on long strings as well (thousands of characters).
When I use the XORSTR macro on string literals with thousands of characters, I get a "recursive type or function dependency context too complex" error during compilation.
I've tried figuring out exactly what the code does, and it seems like these lines recursively construct some kind of compile-time array (?) from the input string, and the ConstructIndexList line is what generates the error:
template <typename IndexList, int Right> struct Append;
template <int... Left, int Right> struct Append<IndexList<Left...>, Right> {
typedef IndexList<Left..., Right> Result;
};
template <int N> struct ConstructIndexList {
typedef typename Append<typename ConstructIndexList<N - 1>::Result, N - 1>::Result Result;
};
Since I have little knowledge of templates, I'm not sure how exactly to approach this problem.
One idea I had was to pass the macro substrings of the original literal and then concatenate them (in a procedural manner, not manually), however...I have no idea how to do compile-time substring/concatenation operations on literals, and maybe that's impossible.
Another idea was to simply split up my literals manually, passing the split strings to XORSTR individually, and then manually concatenating the results, but that creates a lot of mess in my code....considering that I need to run XORSTR on tens of thousands of characters, and the error pops up when >~250 characters are passed to it.
Any other ideas would be appreciated...or if someone has another compile-time string obfuscation implementation that can take string literals of any arbitrary length...that would be great!
Aucun commentaire:
Enregistrer un commentaire