package csgo import ( "encoding/hex" "fmt" "math/big" "regexp" "strings" ) //goland:noinspection SpellCheckingInspection var DICT = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789" var sharecodeRexEx = regexp.MustCompile("^CSGO(?:-?[\\w]{5}){5}$") func DecodeSharecode(code string) (uint64, uint64, uint32, error) { if !sharecodeRexEx.MatchString(code) { return 0, 0, 0, fmt.Errorf("not a CSGO sharecode: %s", code) } cleanCode := strings.ReplaceAll(code, "CSGO", "") cleanCode = strings.ReplaceAll(cleanCode, "-", "") chars := ReverseString(strings.Split(cleanCode, "")) bigInt := new(big.Int) dictLenBig := big.NewInt(int64(len(DICT))) for _, c := range chars { bigInt.Mul(bigInt, dictLenBig) bigInt.Add(bigInt, big.NewInt(int64(strings.Index(DICT, c)))) } bytes := make([]byte, 18) bigInt.FillBytes(bytes) matchId := new(big.Int) matchId.SetString(hex.EncodeToString(Reverse(bytes[0:8])), 16) outcomeId := new(big.Int) outcomeId.SetString(hex.EncodeToString(Reverse(bytes[8:16])), 16) tokenId := new(big.Int) tokenId.SetString(hex.EncodeToString(Reverse(bytes[16:18])), 16) return matchId.Uint64(), outcomeId.Uint64(), uint32(tokenId.Uint64()), nil } func Reverse(numbers []byte) []byte { for i, j := 0, len(numbers)-1; i < j; i, j = i+1, j-1 { numbers[i], numbers[j] = numbers[j], numbers[i] } return numbers } func ReverseString(numbers []string) []string { for i, j := 0, len(numbers)-1; i < j; i, j = i+1, j-1 { numbers[i], numbers[j] = numbers[j], numbers[i] } return numbers }