|
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 |
|
} |
|
|