Files
csgowtfd/csgo/sharecode.go

58 lines
1.5 KiB
Go

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
}