我希望有一个编译时字符串加密,这样我就可以在我的代码中编写:
const auto encryptedInvalidLicense = ENCRYPT("Invalid license");
std::cout << encryptedInvalidLicense.decrypt() << std::endl; // outputs "Invalid license"
字符串“Invalid license”不会出现在二进制文件中。
预构建可能是答案,但我正在寻找一个纯c ++ constexpr
解决这个问题的方法,它将得到VS2015的支持。
有什么建议吗?
我已经调查了Compile-time string encryption,但没有为问题提供constexpr解决方案。
我也研究过http://www.unknowncheats.me/forum/c-and-c/113715-compile-time-string-encryption.html。虽然它是一个constexpr解决方案,但VS2015仍然会将字符串纯文本添加到二进制文件中。
答案 0 :(得分:16)
我将如何做到这一点:
1。)使用str_const
模板进行constexpr字符串操作:Conveniently Declaring Compile-Time Strings in C++
代码:
class str_const {
// constexpr string
private:
const char * const p_;
const std::size_t sz_;
public:
template <std::size_t N>
constexpr str_const(const char(&a)[N])
: p_(a)
, sz_(N - 1)
{}
constexpr char operator[](std::size_t n) const { return n < sz_ ? p_[n] : throw std::out_of_range(""); }
constexpr std::size_t size() const { return sz_; }
constexpr const char * get() const { return p_; }
};
这使您可以执行str_const message = "Invalid license"
之类的操作并在constexpr函数中操作message
。
2.。)使用宏__TIME__
和__LINE__
生成一个简单的编译时伪随机生成器来生成种子。这在此处详细描述:Generate random numbers in C++ at compile time
他们提供了一些基于模板的代码。
3.。)使用constexpr
ctor创建一个结构,它使const char []
和模板本身的大小与str_const
示例类似,或者只需{{1}并生成两个str_const
,它是它的成员变量。
str_const
的{{1}},其中str_const
是输入的长度。 (“噪音串”)n
的{{1}},其中包含具有噪声字符的输入字符的入口和(作为无符号字符)。 (“密文”)然后它有一个成员函数n
,它不需要是constexpr,并且可以返回str_const
,它只是从密文的相应字符中减去噪声字符串的每个字符并返回结果字符串。
如果你的编译器仍然将原始字符串文字存储在二进制文件中,则意味着要么存储输入字符串文字(构造函数参数),我认为它不应该这样做,因为它是临时的,或者它基本上内联n
函数,您应该能够通过使用函数指针对其进行模糊处理,或将其标记为decrypt
或类似函数来阻止它。
编辑:我不确定标准是否要求临时constexpr对象不应出现在二进制文件中。其实我现在很好奇。我的期望是,至少在发布版本中,一个好的编译器应该在不再需要它们时删除它们。
编辑:所以,你已经接受了我的回答。但无论如何,为了完整性,这里有一些实现上述想法的源代码,仅使用C ++ 11标准。它适用于gcc-4.9和clang-3.6,即使在禁用优化时也是如此,我几乎可以告诉它。
std::string
答案 1 :(得分:-1)
我有这样的代码:
#if GENERATE_CODE
.... code to generate the C++ code describing the encrypted literal
.... generating exactly the code in the #else part
#else
static char encryptedLicense [32] = "..."; or whatever
#endif
不要试图聪明。将#if代码复制到一个单独的文件中,编译并运行,然后将结果粘贴回来。