mirror of https://github.com/Xhofe/alist
				
				
				
			
		
			
				
	
	
		
			211 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
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)),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// 带params的SignatureOfHmac HMAC签名
 | 
						|
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)))
 | 
						|
}
 | 
						|
 | 
						|
// RAS 加密用户名密码
 | 
						|
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))
 | 
						|
}
 | 
						|
 | 
						|
// aes 加密params
 | 
						|
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...)
 | 
						|
}
 | 
						|
 | 
						|
// 获取http规范的时间
 | 
						|
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
 | 
						|
}
 | 
						|
 | 
						|
// 计算分片大小
 | 
						|
// 对分片数量有限制
 | 
						|
// 10MIB 20 MIB 999片
 | 
						|
// 50MIB 60MIB 70MIB 80MIB ∞MIB 1999片
 | 
						|
func partSize(size int64) int64 {
 | 
						|
	const DEFAULT = 1024 * 1024 * 10 // 10MIB
 | 
						|
	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 // 20MIB
 | 
						|
	}
 | 
						|
	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
 | 
						|
}
 |