package utils import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "fmt" "strconv" "time" ) const ( // DefaultSignKey is the signing key from the Android app DefaultSignKey = "p93jhgh689SBReK6ghtw62" // DesktopSignKey is the signing key from the desktop app DesktopSignKey = "kzqU4XhfCaY6B6JTHODeq5" // DesktopClient is the X-Yandex-Music-Client header value for desktop DesktopClient = "YandexMusicDesktopAppWindows/5.95.0" ) // Sign represents a request signature type Sign struct { Timestamp int64 Value string } // GetSignRequest creates a signature for a track request func GetSignRequest(trackID string, key string) Sign { if key == "" { key = DefaultSignKey } timestamp := time.Now().Unix() message := trackID + strconv.FormatInt(timestamp, 10) h := hmac.New(sha256.New, []byte(key)) h.Write([]byte(message)) sign := base64.StdEncoding.EncodeToString(h.Sum(nil)) return Sign{ Timestamp: timestamp, Value: sign, } } // GetFileInfoSign creates a signature for file info requests func GetFileInfoSign(trackID, quality string, codecs []string, transport, key string) Sign { if key == "" { key = DesktopSignKey } timestamp := time.Now().Unix() message := fmt.Sprintf("%d%s%s%s%s", timestamp, trackID, quality, joinCodecs(codecs), transport) h := hmac.New(sha256.New, []byte(key)) h.Write([]byte(message)) sign := base64.StdEncoding.EncodeToString(h.Sum(nil)) // Remove last character as in Python if len(sign) > 0 { sign = sign[:len(sign)-1] } return Sign{ Timestamp: timestamp, Value: sign, } } func joinCodecs(codecs []string) string { result := "" for _, c := range codecs { result += c } return result }