生成激活码

工作室的工作流程基本是,产品经理下单,内容具化到思路,算法。工作起来没有一点激情。前两天叫写一个随机生成激活码工具,mark之。

在项目之初,特别是公测前。很多项目都会选择限量导入玩家。个人认为,这样进来的玩家质量会更优质;也增加了测试数据的可靠性;这些体外话。

激活码基本思路如下

首先,确定激活码包含的字符:a~z;0~9,去掉字母o,l。这两个容易跟0,1混淆。每个激活码包含六个随机字符跟两个固定字符。

这样随机部分的样本空间就可以确定了。其实就是34进制的六位数。总大小有1544804416.

我的做法是在1~1544804416之间随机一个数,再转换成34进制的,用map保证结果唯一性。最后再在前面加上两个固定字符,保证不同次生成激活码的唯一性。

我另一个同事的做法是,每次生成的时候在随机数前面加个递增id。然后记住已经生成激活码的个数,保证每次的唯一性。

//取字符样本空间的字符

char GenActive::GetConsult(int consult)
{
if (0 <= consult && consult <= 9)
{
return consult + '0';
}
if (10 <= consult && consult <= 20) //a~k
{
return consult - 10 + 'a';
}
if (21 <= consult && consult <= 22) //m,n
{
return consult - 21 + 'm';
}
if (23 <= consult && consult <= 34) //p~z
{
return consult - 23 + 'p';
}
return 0;
}

//取前两个固定字符

std::string GenActive::GetBatchNum()
{
if (m_nBatchNum > 99)
{
return "99";
}
if (m_nBatchNum < 0)
{
return "00";
}
std::string s = "00";
s[0] = m_nBatchNum / 10 + '0';
s[1] = m_nBatchNum % 10 + '0';

return s;
}

//十进制转34进制

std::string GenActive::Dec2thhex(unsigned long n)
{
std::string sBatchChar = GetBatchNum();
std::string result = "000000";

int i = 0;
std::cout << "n : "<< n;
for (;i < 5 && n > 34;i++)
{
int consult = n % 34;
char r = GetConsult(consult);
result[5 - i] = r;
n = n / 34;
}

result[5 - i] = GetConsult(n);
for(int j = 0; j < 5 - i; j++)
{
result[j] = '0';
}
result = sBatchChar + result;
std::cout << " result :" << result << std::endl;
return result;
}

//生成激活码

bool GenActive::DoGen()
{
int deep = 0;
srand((unsigned)time(NULL));
while (1)
{
deep++;
int a = rand();
unsigned long nRand = a * fmax_active_code / RAND_MAX;
std::string sThhexRand = Dec2thhex(nRand);
std::pair<std::map<unsigned long, std::string>::iterator, bool> Insert_Pair;
Insert_Pair = m_mapResult.insert(std::pair<unsigned long ,std::string>(nRand,sThhexRand));
if (Insert_Pair.second)
{
m_nCount++;
if (m_nCount >= m_nRandNum)
{
break;
}
}
if (deep >= max_loop_deep)
{
break;
}
}
return true;
}

原文地址:https://www.cnblogs.com/zhenzi/p/3426472.html