游戏中唯一id的产生算法

id设计由三个参数产生:游戏的区服id、当前的时间戳、当前计数

  • 设计思路:
  • 64位偏移组合
  • 首先根据区服id的大小,分配适当位数
  • 再根据时间戳的大小,分配适当位数
  • 剩余的位数交于计数
    结合后uuid的组成大致如下所示
tag1-2位
区服id-8位
tag2-2位
当前时间戳-32位
当前计数-20位

下面是具体的算法实现:

package mainimport("fmt""time"
)
//~唯一id产生算法var shiftSizeArr = []uint32{0xff,0xffff,0xffffff,0xffffffff} //~用于判断值的需要的位数const shiftSizeTagSize = 2 //~tag偏移位数
const shiftSizeInterval = 8 //~id头偏移位数 -- 与shiftSizeArr的设置对应// ShiftOffset -- 偏移
// 参数 v -- 值 offset -- 剩余偏移位数 last -- 尾
// 返回 (偏移后的值,剩余偏移量,是否成功)
func ShiftOffset(v uint32,offset int,last bool) (uint64,int,bool) {if offset > 64 {panic("只能产生uint64的唯一id")}if last {//~传入的值超过剩余位数能达到的最大值,产生失败if v > ( 1<<uint32(offset) - 1 ) {return 0,0,false}return uint64(v),0,true}//~判断传入的值需要多少位偏移i := 0for v > shiftSizeArr[i] {i++ if i == len(shiftSizeArr) {return 0,0,false}}//~判断剩余偏移位数是否足够n := (i+1) * shiftSizeIntervalif offset < n + shiftSizeTagSize {return 0,0,false}var ret uint64offset -= shiftSizeTagSizeret += uint64(i) << uint32(offset)offset -= nret += uint64(v) << uint32(offset)return ret,offset,true
}func GenUUID(keys ...uint32) (uint64,bool) {offset := 64var res uint64l := len(keys)for i,k := range keys {v,of,ok := ShiftOffset(k,offset,i+1 == l)if !ok {return 0,false}offset = ofres += v}return res,true
}func main() {fmt.Println("测试开始")n := uint32(time.Now().Unix())m := make(map[uint64]bool)of := 0for of <= 24 {node := 1 << uint32(of)var i uint32for {id,ok := GenUUID(uint32(node),n,i)if !ok {break}if _,ok := m[id];ok{fmt.Printf("id重复 %v\n",id)}m[id] = true  i++}fmt.Printf("node=%v 每个时间戳可以产生 %v 个id\n",node,i)of += shiftSizeInterval}
}

测试结果如下:

node在2^8=256以下时能够产生足够的id,但是当node的id大于256时,产生的id骤减,这个tag占位和扩展8位的粗度有关,有兴趣可以更改参数shiftSizeArr,shiftSizeInterval,不使用shiftSizeTagSize进行进一步测试。

[go游戏开发实践]游戏唯一id产生算法相关推荐

  1. lua游戏开发实践指南光盘_Godot游戏开发实践之一:用High Level Multiplayer API制作多人游戏(上)

    一.前言 距离上一次发文已经稳稳超过一年了,去年一直在做 #¥@#*!%--%#&-%&^# 然后待在家里了!偶尔写写 BUG ,一直默默关注着 Godot ,这不已经 3.2.2 版 ...

  2. lua游戏开发实践指南光盘_Godot游戏开发实践之三:容易被忽视的Resource

    一.前言 首先,特大喜讯,奔走相告, Godot 爱好者们又有新的窝了--我们国人自建的 Godot 论坛:Godot中文社区已经正式开放,这里有一手的开发资源,最新的科技动向,开发上有啥问题可以随时 ...

  3. 做游戏,学编程(C语言)教材《C语言课程设计与游戏开发实践教程》出版了...

    经过半年多的写作.修改.校样.印制,我们的实践教材<C语言课程设计与游戏开发实践教程>终于出版了.这本书可以看成是"做游戏,学编程(C语言)专栏"的详细版本,以下为书中 ...

  4. Android游戏开发实践指南(华章程序员书库)

    <Android游戏开发实践指南(华章程序员书库)> 基本信息 原书名:Learning Android Game Programming:A Hands-On Guide to Buil ...

  5. AndEngine 《Android游戏开发实践指南》之“吸血鬼游戏”实例学习(一)

    购买的<Android游戏开发实践指南>一书用的AndEngine库已经更新过,书上很多代码不适应于AndEngine GLES 2. 根据书上的步骤通过学习<少女大战吸血鬼> ...

  6. iPhone游戏开发实践指南

    <iPhone游戏开发实践指南>前言 编写游戏不是一项轻松的任务,即使你是个经验丰富的程序员,游戏的设计模式.术语和思考过程看上去也会有点奇怪和不合常规.由于我的大部分工作时间都投入到了创 ...

  7. Unity游戏开发之游戏存档方式

    目录 1.Unity自带存储方式PlayerPrefs 2.XML存储方式 3.Json类型存储方式 1.Unity的序列化问题 2.Unity中支持序列化的类 3.Unity中Json的使用方法 4 ...

  8. android策略模式_Android游戏开发–设计游戏实体–策略模式

    android策略模式 在这一部分中,我将尝试解释我对好的游戏设计元素的理解. 我将在示例中使用droid,并编写基本的战斗模拟器脚本以查看其行为. 问题: 我指挥一个机器人,我想消灭敌人. 再次面对 ...

  9. android_Android游戏开发–基本游戏架构

    android 因此,我们启动并运行了我们的Android应用程序,但是您可能想知道哪种类型的应用程序正是游戏. 我会尽力让您了解它. 下图显示了游戏架构. Android手机上的游戏架构 在上面的架 ...

最新文章

  1. CSS3 :nth-child(n)使用注意
  2. 让IE6支持图片半透明
  3. python日历提醒_python打印日历
  4. C++ IO类(3) 文件流
  5. 一个静态库框架模板: iOS Universal Framework Mk 7
  6. 四十三 常用内建模块 base64
  7. python数据结构与算法之问题求解
  8. 【大数据24小时】“天智一号”卫星将在太空计算数据;“电子身份证”亮相支付宝
  9. 打开JMeter报错:Could not reserve enough space for 1048576KB object heap
  10. 那些脱颖而出的云计算认证
  11. USB转串口驱动(支持各平台)
  12. mysql数据库有dbo吗,sql server所有表的所有者恢复为dbo
  13. HDU 6070 Dirt Ratio
  14. 用C语言写Badapple
  15. Reactive 响应式编程简单使用
  16. 安卓期末大作业——单词本APP(源码+任务书)
  17. idea项目打包和部署
  18. http服务器究竟做了什么(一)
  19. 1024程序员节 技术对抗赛 算法与安全答题 标准答案
  20. ANSI最全介绍linux终端字体改变颜色等

热门文章

  1. 如何解决Selenium打不开Ie浏览器
  2. 国际象棋AI(三)---评估
  3. RealView 应用
  4. 百万级PHP网站架构-Poppen.de
  5. 将一个Excel中的数据导入DataGrid中
  6. 服务器上Web.config文件不能保存,Web.Config – 由于权限不足,无法读取configuration文件...
  7. java des ecb_【转】 java DES ECB模式对称加密解密
  8. C#的AES加密解密(ECB)
  9. 区块链 liquity源代码分析之一 赎回奖励trove_open_liquidate
  10. 关于unrecognized selector sent to instanc