util.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. package model
  2. import (
  3. "errors"
  4. "math/rand"
  5. "rocommon/service"
  6. "rocommon/util"
  7. "roserver/serverproto"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. var lastTimeStamp uint64 = 0
  13. var sequence = 0
  14. const (
  15. STAMP_SHIFT_BITS = 22 //时间戳左移位数
  16. ZONE_MASK = 32768 //2^15 15位->32767
  17. ZONE_MASK_MULTI = 0x7fff //15位
  18. SEQUENCE_MASK = 0xfff //12位
  19. SEQUENCE_BITS = 12 //序列号位数
  20. SEQUENCE_MASK_MULTI = 0xffff
  21. //SEQUENCE_BITS_MULTI = 16 //序列号12位
  22. SEQUENCE_BITS_MULTI = 20 //序列号12位
  23. TIMESTAMP_BITS_MULTI = 32 //时间戳占用位数
  24. LOGIC_BITS = 5 //logic ID 5占位
  25. LOGIC_MASK = 0x1f
  26. LOGIC_MASK64 = 0x0000000000007fff
  27. ZONE_MASK64_MULTI = 0x000000000000FFC0
  28. )
  29. //role uuid
  30. func GenerateUid() uint64 {
  31. serviceConfig := service.GetServiceConfig()
  32. zone := serviceConfig.Node.Zone
  33. id := serviceConfig.Node.Id
  34. return GUIDCreate(zone, id)
  35. }
  36. func GenerateUidByZone(zone int) uint64 {
  37. serviceConfig := service.GetServiceConfig()
  38. if zone <= 0 {
  39. zone = serviceConfig.Node.Zone
  40. }
  41. id := serviceConfig.Node.Id
  42. return GUIDCreate(zone, id)
  43. }
  44. func ParseUid(uid uint64) (zone, id int32) {
  45. id = int32(uid & LOGIC_MASK)
  46. zone = int32((uid >> LOGIC_BITS) & LOGIC_MASK64)
  47. return
  48. }
  49. func GUIDCreate(zone, id int) uint64 {
  50. currentTimeStamp := uint64(time.Now().Unix())
  51. if lastTimeStamp == 0 {
  52. lastTimeStamp = currentTimeStamp
  53. }
  54. //zone[2^12] id[2^8]
  55. if zone >= ZONE_MASK || id >= 256 {
  56. util.ErrorF("GUIDCreate zone=%v[%v] id=%v[%v] invalid", zone, ZONE_MASK, id, 256)
  57. return 0
  58. }
  59. if lastTimeStamp == currentTimeStamp {
  60. sequence++
  61. if sequence > SEQUENCE_MASK {
  62. //一秒内尝试的数量超过上限
  63. return 0
  64. }
  65. } else {
  66. lastTimeStamp = currentTimeStamp
  67. sequence = 1
  68. }
  69. //zone -> 2^15
  70. //logicid -> 2^5
  71. var uid uint64 = 0
  72. //前32位时间戳(秒)
  73. uid |= lastTimeStamp << TIMESTAMP_BITS_MULTI
  74. //12位序列号
  75. uid |= uint64(sequence&SEQUENCE_MASK_MULTI) << SEQUENCE_BITS_MULTI
  76. //15位区域id
  77. uid |= uint64(zone&ZONE_MASK_MULTI) << LOGIC_BITS
  78. //左后是逻辑ID(服务器id)
  79. uid |= uint64(id & LOGIC_MASK)
  80. return uid
  81. }
  82. func GUIDCreateTest(zone, id int) uint64 {
  83. currentTimeStamp := uint64(time.Now().Unix())
  84. if lastTimeStamp == 0 {
  85. lastTimeStamp = currentTimeStamp
  86. }
  87. if zone > ZONE_MASK {
  88. return 0
  89. }
  90. if lastTimeStamp == currentTimeStamp {
  91. sequence++
  92. if sequence > 256 {
  93. //一秒内尝试的数量超过上限
  94. return 0
  95. }
  96. } else {
  97. lastTimeStamp = currentTimeStamp
  98. sequence = 1
  99. }
  100. var uid uint64 = 0
  101. //前32位时间戳(秒)
  102. uid |= (lastTimeStamp >> 1) << 23
  103. //16位序列号
  104. uid |= uint64(sequence&SEQUENCE_MASK_MULTI) << 15
  105. //8位区域id
  106. uid |= uint64(zone&ZONE_MASK_MULTI) << 5
  107. //左后是逻辑ID(服务器id)
  108. uid |= uint64(id & LOGIC_MASK)
  109. return uid
  110. }
  111. //item id
  112. var uuidLow uint32 = 0
  113. var uuidHigh uint32 = 1
  114. func UUIDCreate() uint64 {
  115. if uuidLow == 0 {
  116. uuidLow = uint32(time.Now().Unix())
  117. }
  118. uuidHigh++
  119. uuid := uint64(uuidHigh)
  120. uuid <<= 32
  121. uuid += uint64(uuidLow)
  122. return uuid
  123. }
  124. //是否同一天(24点)
  125. func IsSameDay(source int64) bool {
  126. loc := util.GetLoc()
  127. nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc)
  128. sourceTime := time.Unix(source, 0).In(loc)
  129. if nowTime.YearDay() != sourceTime.YearDay() {
  130. return true
  131. }
  132. return false
  133. }
  134. //是否是同一天(24点)
  135. func IsSameDayMs(sourceMs uint64) int {
  136. loc := util.GetLoc()
  137. timeS := int64(sourceMs / 1000)
  138. timeMS := int64(sourceMs % 1000)
  139. tempTime := time.Unix(timeS, timeMS).In(loc)
  140. nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc)
  141. nt1 := nowTime.YearDay()
  142. nt2 := tempTime.YearDay()
  143. if nt1 != nt2 {
  144. return nt1 - nt2
  145. }
  146. return 0
  147. }
  148. //判断是否是同一天true不天, false同一天(凌晨晨5点)
  149. func IsDailyResetHour5(sourceMs uint64) bool {
  150. if sourceMs <= 0 {
  151. return false
  152. }
  153. tempTime := util.GetTimeByUint64(sourceMs)
  154. nowTime := util.GetCurrentTimeNow()
  155. nt1 := nowTime.YearDay()
  156. nt2 := tempTime.YearDay()
  157. deltaDay := nt1 - nt2
  158. if nowTime.Year() != tempTime.Year() {
  159. if isLeapYear(tempTime.Year()) {
  160. deltaDay = 366 - nt2
  161. } else {
  162. deltaDay = 365 - nt2
  163. }
  164. deltaDay += nt1
  165. }
  166. if deltaDay < 0 {
  167. return false
  168. } else if deltaDay == 0 {
  169. if tempTime.Hour() < 5 && nowTime.Hour() >= 5 {
  170. return true
  171. }
  172. } else if deltaDay == 1 {
  173. if tempTime.Hour() < 5 || tempTime.Hour() >= 5 && nowTime.Hour() >= 5 {
  174. return true
  175. }
  176. } else {
  177. return true
  178. }
  179. return false
  180. }
  181. func isLeapYear(year int) bool {
  182. if year%4 == 0 && year%100 != 0 || year%400 == 0 {
  183. return true
  184. }
  185. return false
  186. }
  187. func Str2Num(str string) (int, error) {
  188. if str == "" {
  189. return 0, nil
  190. }
  191. str = strings.Replace(str, "\u00A0", "", -1)
  192. str = strings.Replace(str, "\u0020", "", -1)
  193. str = strings.Replace(str, "\u0009", "", -1)
  194. num, e := strconv.ParseInt(str, 10, 32)
  195. if e != nil {
  196. return 0, errors.New("service invalid num convert error:" + str)
  197. } else {
  198. return int(num), nil
  199. }
  200. }
  201. func Str2NumU64(str string) (uint64, error) {
  202. str = strings.Replace(str, "\u00A0", "", -1)
  203. str = strings.Replace(str, "\u0020", "", -1)
  204. num, e := strconv.ParseUint(str, 10, 64)
  205. if e != nil {
  206. return 0, errors.New("service invalid num convert error:" + str)
  207. } else {
  208. return num, nil
  209. }
  210. }
  211. func Str2Float32(str string) (float32, error) {
  212. str = strings.Replace(str, "\u00A0", "", -1)
  213. str = strings.Replace(str, "\u0020", "", -1)
  214. num, e := strconv.ParseFloat(str, 32)
  215. if e != nil {
  216. return 0, errors.New("service invalid num convert error:" + str)
  217. } else {
  218. return float32(num), nil
  219. }
  220. }
  221. func Str2Float32_2(str string) (float32, float32) {
  222. resList := strings.Split(str, ":")
  223. if len(resList) > 1 {
  224. resType, _ := Str2Float32(resList[0])
  225. resValue, _ := Str2Float32(resList[1])
  226. return resType, resValue
  227. }
  228. return 0, 0
  229. }
  230. func Str2Res(str string) (int32, int32) {
  231. resList := strings.Split(str, ":")
  232. if len(resList) > 1 {
  233. resType, _ := Str2Num(resList[0])
  234. resValue, _ := Str2Num(resList[1])
  235. return int32(resType), int32(resValue)
  236. }
  237. return 0, 0
  238. }
  239. func Str2ResBySep(str string, sep string) (int32, int32) {
  240. resList := strings.Split(str, sep)
  241. if len(resList) > 1 {
  242. resType, _ := Str2Num(resList[0])
  243. resValue, _ := Str2Num(resList[1])
  244. return int32(resType), int32(resValue)
  245. }
  246. return 0, 0
  247. }
  248. func Str2Res_3(str string) (int32, int32, int32) {
  249. resList := strings.Split(str, ":")
  250. if len(resList) >= 3 {
  251. value1, _ := Str2Num(resList[0])
  252. value2, _ := Str2Num(resList[1])
  253. value3, _ := Str2Num(resList[2])
  254. return int32(value1), int32(value2), int32(value3)
  255. }
  256. return 0, 0, 0
  257. }
  258. func Str2Res_4(str string) (int32, int32, int32, int32) {
  259. resList := strings.Split(str, ":")
  260. if len(resList) >= 4 {
  261. value1, _ := Str2Num(resList[0])
  262. value2, _ := Str2Num(resList[1])
  263. value3, _ := Str2Num(resList[2])
  264. value4, _ := Str2Num(resList[3])
  265. return int32(value1), int32(value2), int32(value3), int32(value4)
  266. }
  267. return 0, 0, 0, 0
  268. }
  269. func Str2Res_5(str string) (int32, int32, int32, int32, int32) {
  270. resList := strings.Split(str, ":")
  271. if len(resList) >= 5 {
  272. value1, _ := Str2Num(resList[0])
  273. value2, _ := Str2Num(resList[1])
  274. value3, _ := Str2Num(resList[2])
  275. value4, _ := Str2Num(resList[3])
  276. value5, _ := Str2Num(resList[4])
  277. return int32(value1), int32(value2), int32(value3), int32(value4), int32(value5)
  278. }
  279. return 0, 0, 0, 0, 0
  280. }
  281. //最小堆
  282. type MinHeap struct {
  283. ItemList []int32
  284. }
  285. func (h *MinHeap) Len() int {
  286. return len(h.ItemList)
  287. }
  288. func (h *MinHeap) Less(i, j int) bool {
  289. return h.ItemList[i] < h.ItemList[j]
  290. }
  291. func (h *MinHeap) Swap(i, j int) {
  292. h.ItemList[i], h.ItemList[j] = h.ItemList[j], h.ItemList[i]
  293. }
  294. func (h *MinHeap) Push(item interface{}) {
  295. h.ItemList = append(h.ItemList, item.(int32))
  296. }
  297. func (h *MinHeap) Pop() (ret interface{}) {
  298. l := len(h.ItemList)
  299. h.ItemList, ret = h.ItemList[:l-1], h.ItemList[l-1]
  300. return
  301. }
  302. //随机打乱数组Fisher-Yates随机置乱算法
  303. func GenRandomArray(selfArray []int32) []int32 {
  304. if len(selfArray) <= 0 {
  305. return nil
  306. }
  307. rand.Seed(time.Now().UnixNano())
  308. for i := len(selfArray) - 1; i > 0; i-- {
  309. randNum := rand.Intn(i + 1)
  310. selfArray[i], selfArray[randNum] = selfArray[randNum], selfArray[i]
  311. }
  312. return selfArray
  313. }
  314. func GenRandomArrayByLen(numLen int) []int32 {
  315. if numLen <= 0 {
  316. return nil
  317. }
  318. rand.Seed(time.Now().UnixNano())
  319. var selfArray []int32
  320. for idx := 0; idx < numLen; idx++ {
  321. selfArray = append(selfArray, int32(idx+1))
  322. }
  323. for i := len(selfArray) - 1; i > 0; i-- {
  324. randNum := rand.Intn(i + 1)
  325. selfArray[i], selfArray[randNum] = selfArray[randNum], selfArray[i]
  326. }
  327. return selfArray
  328. }
  329. //字符串相似度算法
  330. func MessageLD(s, t string, ignoreCase bool) int {
  331. if ignoreCase {
  332. s = strings.ToLower(s)
  333. t = strings.ToLower(t)
  334. }
  335. d := make([][]int, len(s)+1)
  336. for i := range d {
  337. d[i] = make([]int, len(t)+1)
  338. }
  339. for i := range d {
  340. d[i][0] = i
  341. }
  342. for j := range d[0] {
  343. d[0][j] = j
  344. }
  345. for j := 1; j <= len(t); j++ {
  346. for i := 1; i <= len(s); i++ {
  347. if s[i-1] == t[j-1] {
  348. d[i][j] = d[i-1][j-1]
  349. } else {
  350. min := d[i-1][j]
  351. if d[i][j-1] < min {
  352. min = d[i][j-1]
  353. }
  354. if d[i-1][j-1] < min {
  355. min = d[i-1][j-1]
  356. }
  357. d[i][j] = min + 1
  358. }
  359. }
  360. }
  361. return d[len(s)][len(t)]
  362. }
  363. //二倍均值算法,count剩余个数,amount剩余金额
  364. func DoubleAverage(count, amount int64) int64 {
  365. //最小钱
  366. min := int64(1)
  367. if count <= 0 {
  368. count = 1
  369. }
  370. if count == 1 {
  371. //返回剩余金额
  372. return amount
  373. }
  374. //计算最大可用金额,min最小是1分钱,减去的min,下面会加上,避免出现0分钱
  375. max := amount - min*count
  376. if max < 0 {
  377. return 0
  378. }
  379. //计算最大可用平均值
  380. avg := max / count
  381. //二倍均值基础加上最小金额,防止0出现,作为上限
  382. avg2 := 2*avg + min
  383. //随机红包金额序列元素,把二倍均值作为随机的最大数
  384. //rand.Seed(time.Now().UnixNano())
  385. //加min是为了避免出现0值,上面也减去了min
  386. x := rand.Int63n(avg2) + min
  387. return x
  388. }
  389. /*
  390. 使用说明
  391. rand.Seed(time.Now().UnixNano())
  392. var sumAmount int64 = 0
  393. var remainAmount int64 = 2
  394. rewardNum := 10
  395. for idx := 0; idx < rewardNum; idx++ {
  396. delAmount := DoubleAverage(int64(rewardNum-idx), int64(remainAmount))
  397. remainAmount -= delAmount
  398. sumAmount += delAmount
  399. log.Printf("delAmount=%v", delAmount)
  400. }
  401. log.Printf("sumAmount=%v", sumAmount)
  402. */
  403. func Str2ResMapList(strList []string, resList map[int32]int32) {
  404. for _, str := range strList {
  405. k, v := Str2Res(str)
  406. if k <= 0 || v <= 0 {
  407. continue
  408. }
  409. resList[k] += v
  410. }
  411. }
  412. func Str2ResSliceList(strList []string) []*serverproto.KeyValueType {
  413. var outList []*serverproto.KeyValueType
  414. for _, str := range strList {
  415. k, v := Str2Res(str)
  416. if k <= 0 || v <= 0 {
  417. continue
  418. }
  419. outList = append(outList, &serverproto.KeyValueType{
  420. Key: k,
  421. Value: v,
  422. })
  423. }
  424. return outList
  425. }