时间:2014.04.09
地点:基地二楼
说明:这些练习尽量按Google C++标准规范编写,环境 VS2013,语言:C++11
--------------------------------------------------------------------------------
某软件需要实现建议的CD-KEY算法,输入3个正整数,以空格隔开,根据这3个整数生成CD-KEY字符串,输出格式XXXX-XXXX-XXXX-XXYY,包括16个字符,以短划线分开,其中,CD-KEY最后两个YY是用于CD-KEY的自校验,确保CD-KEY本身是合法的。
CDKEY使用的字符表23456789ABCDEFGHJKLMNPQRSTUVWXYZ
(由于1和I,0和O不好区分,删除)
请实现CDKEY的生成算法,原理如下:
(1)输入的3个32bit的正整数,按顺序取每个整数的低16bit,假设为a,b,c串联生成一个48bit的环形,然后从低到高,每次去5个bit,并将其作为下标,从32字符表中取出相应字符,循环输出14个字符(提示:第一个输出的字符应该是c的低5bit生成)。
(2)上面输出14个字符即为CDKEY的从左至右的14个字符,将这14个字符按照ascii码方式全部相加,取低10bit,从低到高,查表生成两个校验位。
样例输入:
1 1 1
样例输出:
3224-2262-2A22-J2CR
#include<iostream>
#include<string>
#include<bitset>
using namespace std;
string GenerteCDKey(unsigned num_first,unsigned num_second,unsigned um_third);
//Precondition:
//Postcondition:
string StringReverse(const string& str);
//Precondition:
//Postcondition:
string GenrateCheck(const string& str);
//Precondition:
//Postcondition:
void FormatPrint(const string& str);
//Precondition:
//Postcondition:
int main()
{
unsigned num_first, num_second, num_third;
cin >> num_first >> num_second >> num_third;
string CDKey = GenerteCDKey(num_first, num_second, num_third);
FormatPrint(CDKey);
}
string GenerteCDKey(unsigned num_first, unsigned num_second, unsigned num_third)
{
const string kCharacterTable = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
bitset<16> bitvec_first(num_first), bitvec_second(num_second), bitvec_third(num_third);
string str_cicle = bitvec_first.to_string() + bitvec_second.to_string() + bitvec_third.to_string();
string reverse_string = StringReverse(str_cicle);
bitset<48> bit_cicle(str_cicle);
bitset<5> bit_loop;
size_t index;
string CDKey_left = "",CDKey="";
for (size_t loop = 0; loop < 14; ++loop)
{
for (size_t i = loop*5; i < (loop*5+5);++i)
bit_loop[i%5] = bit_cicle[i%48];
index = bit_loop.to_ulong();
CDKey_left += kCharacterTable[index];
}
CDKey = CDKey_left + GenrateCheck(CDKey_left);
return CDKey;
}
string StringReverse(const string& str)
{
string reverse(48, ‘0‘);
size_t index = 0;
for (auto ch : str)
{
reverse[47-index] = ch;
++index;
}
return reverse;
}
string GenrateCheck(const string& str)
{
const string kCharacterTable = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
unsigned sum = 0;
for (auto ch : str)
sum += ch;
bitset<10> bitset_sum(sum);
bitset<5> bitset_check_one;
bitset<5> bitset_check_two;
for (size_t i = 0; i < 5; ++i)
{
bitset_check_one[i] = bitset_sum[i];
bitset_check_two[i] = bitset_sum[i + 5];
}
size_t index_one = bitset_check_one.to_ulong(), index_two = bitset_check_two.to_ulong();
string check_str = "";
check_str += kCharacterTable[index_one];
check_str += kCharacterTable[index_two];
return check_str;
}
void FormatPrint(const string& str)
{
string out_str="";
for (size_t index = 0; index < 16;++index)
{
out_str += str[index];
if (index % 4 == 3&&index!=15)
out_str += ‘-‘;
}
cout << out_str << endl;
}原文:http://blog.csdn.net/u012333003/article/details/23253543