【转】网游服务器中的GUID(唯一标识码)实现-基于snowflake算法
2024-08-23 02:38:36
本文中的算法采用twitter的snowflake算法,具体请搜索介绍,原来是用Scala写的,因我项目需要,改写成C++语言,主要用于高效的生成唯一的ID, 核心算法就是毫秒级时间(41位)+机器ID(10位)+毫秒内序列(12位).
网上也有好多PHP写的插件模块,核心用了网络通讯将生成的ID发送给PHP使用,没深入研究PHP的模块写法。
废话不多说了,还是直接上代码好了。
uuid.h
#ifndef __UTIL_UUID_H__
#define __UTIL_UUID_H__ #include <stdint.h> namespace utils
{
// twitter snowflake算法
// 64 63--------------22---------12---------0
// 符号位 | 41位时间 |10位机器码|12位自增码|
extern uint64_t get_time(); class unique_id_t
{
public:
unique_id_t();
~unique_id_t(); void set_epoch(uint64_t epoch);
void set_machine(int32_t machine);
int64_t generate(); private:
uint64_t epoch_;
uint64_t time_;
int32_t machine_;
int32_t sequence_;
}; } #endif // !__UTIL_UUID_H__
uuid.cpp
#include "uuid.h"
#if defined(__GUNC__)
#include <sys/time.h>
#include <unistd.h>
#define EPOCHFILETIME 11644473600000000ULL
#else
#include <windows.h>
#include <time.h>
#define EPOCHFILETIME 11644473600000000Ui64
#endif namespace utils
{ uint64_t get_time()
{
#ifdef __GUNC__
struct timeval tv;
gettimeofday(&tv,NULL); uint64 time = tv.tv_usec;
time /= 1000;
time += (tv.tv_sec * 1000);
return time;
#else
FILETIME filetime;
uint64_t time = 0; GetSystemTimeAsFileTime(&filetime);
time |= filetime.dwHighDateTime;
time <<= 32;
time |= filetime.dwLowDateTime;
time /= 10;
time -= EPOCHFILETIME;
return time / 1000;
#endif
} unique_id_t::unique_id_t()
{
epoch_ = 0;
time_ = 0;
machine_ = 0;
sequence_ = 0;
} unique_id_t::~unique_id_t()
{ } void unique_id_t::set_epoch(uint64_t epoch)
{
epoch_ = epoch;
} void unique_id_t::set_machine(int32_t machine)
{
machine_ = machine;
} int64_t unique_id_t::generate()
{
int64_t value = 0;
uint64_t time = get_time() - epoch_;
// 保留后41位时间
value = time << 22;
// 中间10位是机器ID
value |= (machine_ & 0x3FF) << 12;
// 最后12位是sequenceID
value |= sequence_++ & 0xFFF;
if (sequence_ == 0x1000)
{
sequence_ = 0;
}
return value;
}
} #ifdef __TEST__ #include <iostream> void test()
{
utils::unique_id_t*
u_id_ptr = new utils::unique_id_t();
u_id_ptr->set_epoch(uint64_t(1367505795100));
u_id_ptr->set_machine(int32_t(100));
for (int i = 0; i < 1024; ++i)
{
std::cout << u_id_ptr->generate() << std::endl;;
}
} #endif
这样的唯一ID就可以用来表示你系统中使用的例如物品唯一ID,坐骑唯一ID等等数据,方便记录和追踪。
最新文章
- Money, save or spend, this is a problem .
- UI第十九节——UICollectionView
- Windows装机必备软件列表
- 28Spring_的事务管理_银行转账业务加上事务控制_基于注解进行声明式事务管理
- 夜黑风高的夜晚用SQL语句做了一些想做的事&#183;&#183;&#183;&#183;&#183;&#183;&#183;
- Jquery each 的跳出 break continue
- 蓝桥杯 入门训练 Fibonacci数列
- HDU 1978 How many ways (DP)
- 【转】ArrayList的toArray,也就是list.toArray[new String[list.size()]];,即List转为数组
- 『零行代码』解决键盘遮挡问题(iOS)
- nodejs学习记录
- 最近写的页面,含有大量的ajax
- (图文教程)帝国cms7.0列表页模板调用多说评论次数
- windows简单杀死进程的批处理程序
- 【Leetcod】Unique Binary Search Trees II
- Python实现基于协程的异步爬虫
- 从零开始学安全(三十七)●VM汇编环境搭建
- Java开发笔记(四十二)日历工具的常见应用
- SqlServer 行转列,列转行 以及PIVOT函数快速实现行转列,UNPIVOT实现列转行
- Java学习笔记之——数组