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; } }