123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- package hashgen
- import (
- "encoding/hex"
- "errors"
- "fmt"
- "sync"
- "time"
- "github.com/patrickmn/go-cache"
- "github.com/sirupsen/logrus"
- "gogs.daxia.dev/huanan/pkg.daxia.dev/encrypt"
- "gogs.daxia.dev/huanan/pkg.daxia.dev/time_utils"
- )
- var openNumberCache *cache.Cache
- var openNumberCacheLocker = sync.Mutex{}
- type HashItem []byte
- const HashCount = 100000
- func Init() {
- for {
- //同步今天,和明天
- timeNow := time.Now()
- today := time_utils.GetFormatTime(timeNow)
- yesterday := time_utils.GetFormatTime(timeNow.Add(time.Hour * -24))
- cacheHash(today)
- cacheHash(yesterday)
- <-time.After(15 * time.Minute)
- }
- }
- func cacheHash(dayStr string) {
- cache := getCacheInstance()
- key := "on_" + dayStr
- _, exists := cache.Get(key)
- if exists {
- return
- }
- openNumberModelInterface := genOpenNumberHashItem(dayStr)
- logrus.Infof("cache hash:%s-%v", dayStr, len(openNumberModelInterface))
- cache.Set(key, openNumberModelInterface, 48*time.Hour)
- }
- func GetOpenNumber(dayStr string, roomID int32, clientHash []byte, index int32) ([]string, string, error) {
- cache := getCacheInstance()
- key := "on_" + dayStr
- openNumberModelInterface, exists := cache.Get(key)
- if !exists {
- return nil, "", errors.New("not exists:" + key)
- }
- hashItemList := openNumberModelInterface.([]HashItem)
- serverHash := hashItemList[HashCount-index-1] //index从0开始,用最后一期,表示第一期
- openNumList, _ := GetRoomOpenNumber(int(roomID), serverHash, clientHash)
- return openNumList, hex.EncodeToString(serverHash), nil
- }
- func getCacheInstance() *cache.Cache {
- openNumberCacheLocker.Lock()
- defer openNumberCacheLocker.Unlock()
- if openNumberCache != nil {
- return openNumberCache
- }
- openNumberCache = cache.New(48*time.Hour, 2*48*time.Hour)
- openNumberCache.OnEvicted(func(name string, val interface{}) {
- //
- })
- return openNumberCache
- }
- func genOpenNumberHashItem(day string) []HashItem {
- seed := encrypt.KeyDataSHA256([]byte("D40163E6E6E35A2204059B0F1121D2DF" + day))
- hashList := make([]HashItem, HashCount)
- hashA := seed
- for i := 0; i < HashCount; i++ {
- hashItem := encrypt.KeyDataSHA256(hashA)
- hashA = hashItem
- hashList[i] = hashItem
- }
- return hashList
- }
- func GetRoomOpenNumber(roomID int, hashItem, clientHash []byte) ([]string, string) {
- resultStrList := make([]string, 5)
- roomHashItem := getRoomHash(hashItem, roomID)
- hashItem = encrypt.KeyDataSHA256(append(roomHashItem, clientHash...))
- cardList := calNum(hashItem)
- resultStrList[0] = fmt.Sprintf("%s,%s,%s,%s,%s", cardList[0], cardList[5], cardList[10], cardList[15], cardList[20])
- resultStrList[1] = fmt.Sprintf("%s,%s,%s,%s,%s", cardList[1], cardList[6], cardList[11], cardList[16], cardList[21])
- resultStrList[2] = fmt.Sprintf("%s,%s,%s,%s,%s", cardList[2], cardList[7], cardList[12], cardList[17], cardList[22])
- resultStrList[3] = fmt.Sprintf("%s,%s,%s,%s,%s", cardList[3], cardList[8], cardList[13], cardList[18], cardList[23])
- resultStrList[4] = fmt.Sprintf("%s,%s,%s,%s,%s", cardList[4], cardList[9], cardList[14], cardList[19], cardList[24])
- return resultStrList, hex.EncodeToString(hashItem)
- }
- func getRoomHash(hashItem []byte, roomID int) []byte {
- roomHash := encrypt.GetMD5HashString(fmt.Sprintf("room_hash_%d", roomID))
- hashItem = encrypt.KeyDataSHA256(append(hashItem, roomHash...))
- return hashItem
- }
- func calNum(hashData []byte) []string {
- resultStrList := make([]string, 25)
- filterMap := map[string]bool{}
- offset := 0
- for i := 0; i < 25; i++ {
- item := fmt.Sprintf("%d", (int(hashData[i])+offset)%52) //生成[0-51]
- _, exists := filterMap[item]
- if exists {
- offset++
- i--
- continue
- }
- resultStrList[i] = item
- filterMap[item] = true
- offset = 0
- }
- return resultStrList
- }
|