| | package _189pc |
| |
|
| | import ( |
| | "bytes" |
| | "crypto/aes" |
| | "crypto/hmac" |
| | "crypto/rand" |
| | "crypto/rsa" |
| | "crypto/sha1" |
| | "crypto/x509" |
| | "encoding/hex" |
| | "encoding/pem" |
| | "encoding/xml" |
| | "fmt" |
| | "math" |
| | "net/http" |
| | "regexp" |
| | "strings" |
| | "time" |
| |
|
| | "github.com/alist-org/alist/v3/pkg/utils/random" |
| | ) |
| |
|
| | func clientSuffix() map[string]string { |
| | rand := random.Rand |
| | return map[string]string{ |
| | "clientType": PC, |
| | "version": VERSION, |
| | "channelId": CHANNEL_ID, |
| | "rand": fmt.Sprintf("%d_%d", rand.Int63n(1e5), rand.Int63n(1e10)), |
| | } |
| | } |
| |
|
| | |
| | func signatureOfHmac(sessionSecret, sessionKey, operate, fullUrl, dateOfGmt, param string) string { |
| | urlpath := regexp.MustCompile(`://[^/]+((/[^/\s?#]+)*)`).FindStringSubmatch(fullUrl)[1] |
| | mac := hmac.New(sha1.New, []byte(sessionSecret)) |
| | data := fmt.Sprintf("SessionKey=%s&Operate=%s&RequestURI=%s&Date=%s", sessionKey, operate, urlpath, dateOfGmt) |
| | if param != "" { |
| | data += fmt.Sprintf("¶ms=%s", param) |
| | } |
| | mac.Write([]byte(data)) |
| | return strings.ToUpper(hex.EncodeToString(mac.Sum(nil))) |
| | } |
| |
|
| | |
| | func RsaEncrypt(publicKey, origData string) string { |
| | block, _ := pem.Decode([]byte(publicKey)) |
| | pubInterface, _ := x509.ParsePKIXPublicKey(block.Bytes) |
| | data, _ := rsa.EncryptPKCS1v15(rand.Reader, pubInterface.(*rsa.PublicKey), []byte(origData)) |
| | return strings.ToUpper(hex.EncodeToString(data)) |
| | } |
| |
|
| | |
| | func AesECBEncrypt(data, key string) string { |
| | block, _ := aes.NewCipher([]byte(key)) |
| | paddingData := PKCS7Padding([]byte(data), block.BlockSize()) |
| | decrypted := make([]byte, len(paddingData)) |
| | size := block.BlockSize() |
| | for src, dst := paddingData, decrypted; len(src) > 0; src, dst = src[size:], dst[size:] { |
| | block.Encrypt(dst[:size], src[:size]) |
| | } |
| | return strings.ToUpper(hex.EncodeToString(decrypted)) |
| | } |
| |
|
| | func PKCS7Padding(ciphertext []byte, blockSize int) []byte { |
| | padding := blockSize - len(ciphertext)%blockSize |
| | padtext := bytes.Repeat([]byte{byte(padding)}, padding) |
| | return append(ciphertext, padtext...) |
| | } |
| |
|
| | |
| | func getHttpDateStr() string { |
| | return time.Now().UTC().Format(http.TimeFormat) |
| | } |
| |
|
| | |
| | func timestamp() int64 { |
| | return time.Now().UTC().UnixNano() / 1e6 |
| | } |
| |
|
| | func MustParseTime(str string) *time.Time { |
| | lastOpTime, _ := time.ParseInLocation("2006-01-02 15:04:05 -07", str+" +08", time.Local) |
| | return &lastOpTime |
| | } |
| |
|
| | type Time time.Time |
| |
|
| | func (t *Time) UnmarshalJSON(b []byte) error { return t.Unmarshal(b) } |
| | func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error { |
| | b, err := e.Token() |
| | if err != nil { |
| | return err |
| | } |
| | if b, ok := b.(xml.CharData); ok { |
| | if err = t.Unmarshal(b); err != nil { |
| | return err |
| | } |
| | } |
| | return e.Skip() |
| | } |
| | func (t *Time) Unmarshal(b []byte) error { |
| | bs := strings.Trim(string(b), "\"") |
| | var v time.Time |
| | var err error |
| | for _, f := range []string{"2006-01-02 15:04:05 -07", "Jan 2, 2006 15:04:05 PM -07"} { |
| | v, err = time.ParseInLocation(f, bs+" +08", time.Local) |
| | if err == nil { |
| | break |
| | } |
| | } |
| | *t = Time(v) |
| | return err |
| | } |
| |
|
| | type String string |
| |
|
| | func (t *String) UnmarshalJSON(b []byte) error { return t.Unmarshal(b) } |
| | func (t *String) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error { |
| | b, err := e.Token() |
| | if err != nil { |
| | return err |
| | } |
| | if b, ok := b.(xml.CharData); ok { |
| | if err = t.Unmarshal(b); err != nil { |
| | return err |
| | } |
| | } |
| | return e.Skip() |
| | } |
| | func (s *String) Unmarshal(b []byte) error { |
| | *s = String(bytes.Trim(b, "\"")) |
| | return nil |
| | } |
| |
|
| | func toFamilyOrderBy(o string) string { |
| | switch o { |
| | case "filename": |
| | return "1" |
| | case "filesize": |
| | return "2" |
| | case "lastOpTime": |
| | return "3" |
| | default: |
| | return "1" |
| | } |
| | } |
| |
|
| | func toDesc(o string) string { |
| | switch o { |
| | case "desc": |
| | return "true" |
| | case "asc": |
| | fallthrough |
| | default: |
| | return "false" |
| | } |
| | } |
| |
|
| | func ParseHttpHeader(str string) map[string]string { |
| | header := make(map[string]string) |
| | for _, value := range strings.Split(str, "&") { |
| | if k, v, found := strings.Cut(value, "="); found { |
| | header[k] = v |
| | } |
| | } |
| | return header |
| | } |
| |
|
| | func MustString(str string, err error) string { |
| | return str |
| | } |
| |
|
| | func BoolToNumber(b bool) int { |
| | if b { |
| | return 1 |
| | } |
| | return 0 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func partSize(size int64) int64 { |
| | const DEFAULT = 1024 * 1024 * 10 |
| | if size > DEFAULT*2*999 { |
| | return int64(math.Max(math.Ceil((float64(size)/1999) /float64(DEFAULT)) , 5) * DEFAULT) |
| | } |
| | if size > DEFAULT*999 { |
| | return DEFAULT * 2 |
| | } |
| | return DEFAULT |
| | } |
| |
|
| | func isBool(bs ...bool) bool { |
| | for _, b := range bs { |
| | if b { |
| | return true |
| | } |
| | } |
| | return false |
| | } |
| |
|
| | func IF[V any](o bool, t V, f V) V { |
| | if o { |
| | return t |
| | } |
| | return f |
| | } |
| |
|