網(wǎng)游服務器中的GUID(唯一標識碼)實現(xiàn)-基于snowflake算法
轉載自:http://www.cppfans.org/1623.html
本文中的算法采用twitter的snowflake算法,具體請搜索介紹,原來是用Scala寫的,因我項目需要,改寫成C++語言,主要用于高效的生成唯一的ID, 核心算法就是毫秒級時間(41位)+機器ID(10位)+毫秒內(nèi)序列(12位).
網(wǎng)上也有好多PHP寫的插件模塊,核心用了網(wǎng)絡通訊將生成的ID發(fā)送給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就可以用來表示你系統(tǒng)中使用的例如物品唯一ID,坐騎唯一ID等等數(shù)據(jù),方便記錄和追蹤。
轉載請注明:C++愛好者博客 » 網(wǎng)游服務器中的GUID(唯一標識碼)實現(xiàn)-基于snowflake算法
posted on 2014-05-29 01:33 楊粼波 閱讀(883) 評論(0) 編輯 收藏 引用 所屬分類: C++