-
Notifications
You must be signed in to change notification settings - Fork 17
/
nt.go
69 lines (61 loc) · 1.68 KB
/
nt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package pool
import (
"encoding/base64"
"errors"
"fmt"
"regexp"
"github.com/FloatTech/floatbox/binary"
)
const (
ntcacheurlprefix = "https://multimedia.nt.qq.com.cn/download?appid=1407&fileid="
ntcacheurl = ntcacheurlprefix + "%s&spec=0&rkey=%s"
ntappidlen = 60
ntrkeylen = 46
ntrawlen = ntappidlen + ntrkeylen
)
var ntcachere = regexp.MustCompile(`^https://multimedia.nt.qq.com.cn/download\?appid=1407&fileid=([0-9a-zA-Z_-]+)&spec=0&rkey=([0-9a-zA-Z_-]+)$`)
var (
ErrInvalidNTURL = errors.New("invalid nt url")
ErrInvalidNTRaw = errors.New("invalid nt raw")
)
type nturl string
func unpack(raw string) (nturl, error) {
if len(raw) != ntrawlen {
return "", ErrInvalidNTRaw
}
rb := binary.StringToBytes(raw)
b := rb[ntappidlen-1]
fileid := base64.RawURLEncoding.EncodeToString(rb[:59])
if len(fileid) < int(b) {
return "", ErrInvalidNTRaw
}
fileid = fileid[:b]
rkey := base64.RawURLEncoding.EncodeToString(rb[60:])
b = rb[ntrawlen-1]
if len(rkey) < int(b) {
return "", ErrInvalidNTRaw
}
rkey = rkey[:b]
return nturl(fmt.Sprintf(ntcacheurl, fileid, rkey)), nil
}
// pack url into pool
func (nu nturl) pack() (string, error) {
subs := ntcachere.FindStringSubmatch(string(nu))
if len(subs) != 3 {
return "", ErrInvalidNTURL
}
var buf [ntrawlen]byte
fileid := subs[1]
rkey := subs[2]
_, err := base64.RawURLEncoding.Decode(buf[:ntappidlen], binary.StringToBytes(fileid))
if err != nil {
return "", err
}
buf[ntappidlen-1] = byte(len(fileid))
_, err = base64.RawURLEncoding.Decode(buf[ntappidlen:], binary.StringToBytes(rkey))
if err != nil {
return "", err
}
buf[ntrawlen-1] = byte(len(rkey))
return binary.BytesToString(buf[:]), nil
}