stick-房间号加密混淆可逆
在上篇 战斗服管理器横向扩展 的基础上 根据房间号自动定位到目标组和房间 直接找到房间目标的管理器,而不用通过redis什么的中转 ,一般生成的还是在4-6 位数里面, 7 8 位都是整个服务器 组N多才能出现
//房间号加密 可逆算法 用于快速定位 组id 和房间号 并且给玩家看的
// 这里的rid 并不是 战斗服的rid 而是房间的顺序编号 应该是1 2 3 4 5 6 开始 表示房间数量 真正用到战斗服还需要转换一次
//内容包含了 服务器组id 和战斗服房间信息
//最多1000台机器 10位 最多每个机器内部4000个房间 那么 4086 占用12位 即22位 最大
/*
原始代码
//1024占用10位
//encode
unsigned int id = 0;
{
int r = rand() % 500 + 1;
int rr = r << 10;//999 max
int gid = 1;// rand() % 800 + 1;
int ggid = gid ^ 1011;
id = rr | ggid;
cout << "encode:" << "r=" << r << " gid=" << gid << " id=" << id << endl;
}
{//decode
int r = id >> 10;
unsigned int ggid = id << 22;
ggid >>= 22;
int gid = ggid ^ 1011;
cout << "decode r=" << r << " gid=" << gid << endl;
}
*/
unsigned int encode(unsigned int gid, unsigned int rid)
{
//不混淆 rid的话 生成的位数不固定
//rid ^= 345;//混淆,但是不能超过12位比特 不然数据会丢失 12位即4096
rid <<= 10;
gid ^= 1011;//混淆,但是不能超过12位比特 不然数据会丢失 12位即4096
return rid | gid;
}
unsigned int decodeGid(unsigned int id)
{
id <<= 22;
id >>= 22;
return (id ^ 1011);
}
unsigned int decodeRid(unsigned int id)
{
return (id >> 10);
//^ 345;
}
struct __Block
{
unsigned int gid;
unsigned int rid;
__Block(unsigned int gid, unsigned int rid)
{
this->gid = gid;
this->rid = rid;
}
};
void AutoTestAlg()
{
std::map<unsigned int, __Block * > mapping;
//test encode is conflict ?
for (int rid = 1; rid < 4000; rid++)
{
for (int gid = 1; gid < 1000; gid++)
{
unsigned int id = encode(gid, rid);
if (mapping.find(id) != mapping.end())
{
cout << "error of id=" << id << " gid=" << gid << " rid=" << rid << endl;
}
mapping.insert(std::make_pair(id, new __Block(gid, rid)));
}
}
//test decode
for (auto it : mapping)
{
int rid = decodeRid(it.first);
int gid = decodeGid(it.first);
if (rid != it.second->rid || gid != it.second->gid)
{
cout << "error of id=" << it.first << " gid=" << gid << " rid=" << rid << endl;
}
}
cout << "test done" << endl;
}
void Test1()
{
for (int i = 0; i < 30; i++)
{
int gid = rand() % 1000;
int rid = rand() % 100;
auto id = encode(gid, rid);
cout << id << endl;
}
}