gpt4 book ai didi

c++ - 用编译时生成的随机 ID 替换魔法 ID 号

转载 作者:行者123 更新时间:2023-12-01 11:24:38 30 4
gpt4 key购买 nike

我的应用程序包含许多 ID。我希望最终让其他人可以查看代码,但不能让运行时逆向工程师轻松查找容易知道的 ID。此外,在开发过程中,在日志文件中使用常量 ID 以便于调试是很有帮助的。但在运行时,我想通过在发布编译期间生成这些 ID 来随机生成它们。使用 <random> 的建议代码可以在 GetRandomId1() 中看到 lib以下。 constexpr使它们在代码中的使用成为可能,就像在 switch 语句中一样。但是,我在使用 constexpr 时遇到问题在我建议的功能中,因为 <random>不是 constexpr兼容的。有没有另一种在编译时生成随机数的方法?或者在编译时生成随机数以在运行时用作常量,这与 constexpr 的概念相悖。 ?

#include <iostream>
#include <random>

// this is the code I would like to use to generate a random number at compile time
/*constexpr */int GetRandomId1()
{
std::random_device rd; // non-deterministic seed
std::mt19937 gen( rd() ); // with constexpr uncommented:
// error C3250: 'rd': declaration is not allowed in 'constexpr' function body
// error C3249: illegal statement or sub-expression for 'constexpr' function
// error C3250: 'gen': declaration is not allowed in 'constexpr' function body

std::uniform_int_distribution<> distri( 1000, 9999 ); // with constexpr uncommented:
// error C3250: 'distri': declaration is not allowed in 'constexpr' function bod
// error C3249: illegal statement or sub-expression for 'constexpr' function
// error C2134: 'std::uniform_int<_Ty>::operator ()': call does not result in a constant expression

return distri( gen );
}

// this code is what works so far
constexpr int GetRandomId2()
{
return 22; // how to make somewhat random?
}

constexpr int AAA = 10;
//constexpr int AAA = GetRandonId1(); // error: is not constexpr function
constexpr int BBB = GetRandomId2(); // ok

void Func1( long ab )
{
switch( ab )
{
case AAA:
std::cout << AAA << std::endl;
break;

case BBB:
std::cout << BBB << std::endl;
break;
}
}

int main()
{
Func1( 22 ); // ok: prints 22

return 0;
}

我正在寻找一种直接的、可维护的解决方案,就像我提出的那样,而不像 How can I generate dense unique type IDs at compile time? 中建议的那样大量使用模板。 .同样在这篇文章中,@jmihalicza 指向 Random number generator for C++ template metaprograms研究论文。本文描述了使用模板元编程的编译时随机数生成,这是一项复杂的尝试,可完成 IMO constexpr 的任务。是(我敢说,还是应该?)设计的。

由于应用程序架构的原因,我不必担心 ID 冲突,所以这不是问题。应用程序代码将确保不会返回重复项。

最佳答案

我给了constexpr随机数生成器 here前段时间,为了constexpr的相关目的字符串加密以帮助对抗您关注的相同对手。

我认为它具有与 mt19937 相当的加密安全性,它是(一个非常复杂的)线性反馈生成器,无论如何都不是真正的加密安全。

这段代码的想法是使用 __TIME____LINE__作为生成器的种子。

typedef uint32_t u32;
typedef uint64_t u64;
typedef unsigned char uchar;

template<u32 S, u32 A = 16807UL, u32 C = 0UL, u32 M = (1UL<<31)-1>
struct LinearGenerator {
static const u32 state = ((u64)S * A + C) % M;
static const u32 value = state;
typedef LinearGenerator<state> next;
struct Split { // Leapfrog
typedef LinearGenerator< state, A*A, 0, M> Gen1;
typedef LinearGenerator<next::state, A*A, 0, M> Gen2;
};
};

// Metafunction to get a particular index from generator
template<u32 S, std::size_t index>
struct Generate {
static const uchar value = Generate<LinearGenerator<S>::state, index - 1>::value;
};

template<u32 S>
struct Generate<S, 0> {
static const uchar value = static_cast<uchar> (LinearGenerator<S>::value);
};


// Seed

#define RNG_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) + \
(__LINE__ * 100000)

我没有尝试使用 constexpr 重写它而不是模板,但我认为在 C++11 标准中使用 constexpr任何复杂的函数并不比模板好得多。只有在 C++14 标准中才会真正变得很好,当你实际上可以拥有局部变量等等。

无论如何,它仍然不应该那么难,这个生成器实现并没有那么糟糕。

你绝对需要放弃与 std::random_device交谈的梦想虽然在编译时。 IIRC,在 libc++实现,这基本上是 std::fopen("/dev/urandom") 上的一个薄包装器.我不知道任何允许在 constexpr 内进行文件系统操作的 C++ 标准或提案计算。 :)

关于c++ - 用编译时生成的随机 ID 替换魔法 ID 号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38593880/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com