refactor: qmc don't export internal functions

pull/41/head
Unlock Music Dev 2 years ago
parent b275b552ed
commit 4365628bff
No known key found for this signature in database
GPG Key ID: 95202E10D3413A1D

@ -8,7 +8,7 @@ type mapCipher struct {
size int size int
} }
func NewMapCipher(key []byte) (*mapCipher, error) { func newMapCipher(key []byte) (*mapCipher, error) {
if len(key) == 0 { if len(key) == 0 {
return nil, errors.New("qmc/cipher_map: invalid key size") return nil, errors.New("qmc/cipher_map: invalid key size")
} }

@ -39,7 +39,7 @@ func Test_mapCipher_Decrypt(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("load testing data failed: %s", err) t.Fatalf("load testing data failed: %s", err)
} }
c, err := NewMapCipher(key) c, err := newMapCipher(key)
if err != nil { if err != nil {
t.Errorf("init mapCipher failed: %s", err) t.Errorf("init mapCipher failed: %s", err)
return return

@ -12,9 +12,9 @@ type rc4Cipher struct {
n int n int
} }
// NewRC4Cipher creates and returns a new rc4Cipher. The key argument should be the // newRC4Cipher creates and returns a new rc4Cipher. The key argument should be the
// RC4 key, at least 1 byte and at most 256 bytes. // RC4 key, at least 1 byte and at most 256 bytes.
func NewRC4Cipher(key []byte) (*rc4Cipher, error) { func newRC4Cipher(key []byte) (*rc4Cipher, error) {
n := len(key) n := len(key)
if n == 0 { if n == 0 {
return nil, errors.New("qmc/cipher_rc4: invalid key size") return nil, errors.New("qmc/cipher_rc4: invalid key size")

@ -37,7 +37,7 @@ func Test_rc4Cipher_Decrypt(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("load testing data failed: %s", err) t.Fatalf("load testing data failed: %s", err)
} }
c, err := NewRC4Cipher(key) c, err := newRC4Cipher(key)
if err != nil { if err != nil {
t.Errorf("init rc4Cipher failed: %s", err) t.Errorf("init rc4Cipher failed: %s", err)
return return
@ -55,7 +55,7 @@ func BenchmarkRc4Cipher_Decrypt(b *testing.B) {
if err != nil { if err != nil {
b.Fatalf("load testing data failed: %s", err) b.Fatalf("load testing data failed: %s", err)
} }
c, err := NewRC4Cipher(key) c, err := newRC4Cipher(key)
if err != nil { if err != nil {
b.Errorf("init rc4Cipher failed: %s", err) b.Errorf("init rc4Cipher failed: %s", err)
return return
@ -72,7 +72,7 @@ func Test_rc4Cipher_encFirstSegment(t *testing.T) {
t.Fatalf("load testing data failed: %s", err) t.Fatalf("load testing data failed: %s", err)
} }
t.Run("first-block(0~128)", func(t *testing.T) { t.Run("first-block(0~128)", func(t *testing.T) {
c, err := NewRC4Cipher(key) c, err := newRC4Cipher(key)
if err != nil { if err != nil {
t.Errorf("init rc4Cipher failed: %s", err) t.Errorf("init rc4Cipher failed: %s", err)
return return
@ -91,7 +91,7 @@ func Test_rc4Cipher_encASegment(t *testing.T) {
} }
t.Run("align-block(128~5120)", func(t *testing.T) { t.Run("align-block(128~5120)", func(t *testing.T) {
c, err := NewRC4Cipher(key) c, err := newRC4Cipher(key)
if err != nil { if err != nil {
t.Errorf("init rc4Cipher failed: %s", err) t.Errorf("init rc4Cipher failed: %s", err)
return return
@ -102,7 +102,7 @@ func Test_rc4Cipher_encASegment(t *testing.T) {
} }
}) })
t.Run("simple-block(5120~10240)", func(t *testing.T) { t.Run("simple-block(5120~10240)", func(t *testing.T) {
c, err := NewRC4Cipher(key) c, err := newRC4Cipher(key)
if err != nil { if err != nil {
t.Errorf("init rc4Cipher failed: %s", err) t.Errorf("init rc4Cipher failed: %s", err)
return return

@ -1,6 +1,6 @@
package qmc package qmc
func NewStaticCipher() *staticCipher { func newStaticCipher() *staticCipher {
return &defaultStaticCipher return &defaultStaticCipher
} }

@ -21,7 +21,7 @@ func simpleMakeKey(salt byte, length int) []byte {
const rawKeyPrefixV2 = "QQMusic EncV2,Key:" const rawKeyPrefixV2 = "QQMusic EncV2,Key:"
func DecryptKey(rawKey []byte) ([]byte, error) { func deriveKey(rawKey []byte) ([]byte, error) {
rawKeyDec := make([]byte, base64.StdEncoding.DecodedLen(len(rawKey))) rawKeyDec := make([]byte, base64.StdEncoding.DecodedLen(len(rawKey)))
n, err := base64.StdEncoding.Decode(rawKeyDec, rawKey) n, err := base64.StdEncoding.Decode(rawKeyDec, rawKey)
if err != nil { if err != nil {

@ -43,13 +43,13 @@ func TestDecryptKey(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("load test data failed: %s", err) t.Fatalf("load test data failed: %s", err)
} }
got, err := DecryptKey(raw) got, err := deriveKey(raw)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("DecryptKey() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("deriveKey() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
if !reflect.DeepEqual(got, want) { if !reflect.DeepEqual(got, want) {
t.Errorf("DecryptKey() got = %v..., want %v...", t.Errorf("deriveKey() got = %v..., want %v...",
string(got[:32]), string(want[:32])) string(got[:32]), string(want[:32]))
} }
}) })

@ -28,18 +28,16 @@ type Decoder struct {
// Validate should call before Read to check if the file is valid. // Validate should call before Read to check if the file is valid.
func (d *Decoder) Read(p []byte) (int, error) { func (d *Decoder) Read(p []byte) (int, error) {
n := len(p) n := len(p)
if d.audioLen-d.offset <= 0 { if d.audioLen <= d.offset {
return 0, io.EOF return 0, io.EOF
} else if d.audioLen-d.offset < n { } else if d.audioLen-d.offset < n {
n = d.audioLen - d.offset n = d.audioLen - d.offset
} }
m, err := d.r.Read(p[:n]) m, err := d.r.Read(p[:n])
if m == 0 { if m > 0 {
return 0, err
}
d.cipher.Decrypt(p[:m], d.offset) d.cipher.Decrypt(p[:m], d.offset)
d.offset += m d.offset += m
}
return m, err return m, err
} }
@ -51,17 +49,17 @@ func NewDecoder(r io.ReadSeeker) (*Decoder, error) {
} }
if len(d.decodedKey) > 300 { if len(d.decodedKey) > 300 {
d.cipher, err = NewRC4Cipher(d.decodedKey) d.cipher, err = newRC4Cipher(d.decodedKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else if len(d.decodedKey) != 0 { } else if len(d.decodedKey) != 0 {
d.cipher, err = NewMapCipher(d.decodedKey) d.cipher, err = newMapCipher(d.decodedKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else { } else {
d.cipher = NewStaticCipher() d.cipher = newStaticCipher()
} }
_, err = d.r.Seek(0, io.SeekStart) _, err = d.r.Seek(0, io.SeekStart)
@ -110,7 +108,7 @@ func (d *Decoder) searchKey() error {
return errors.New("qmc: file with 'STag' suffix doesn't contains media key") return errors.New("qmc: file with 'STag' suffix doesn't contains media key")
} else { } else {
size := binary.LittleEndian.Uint32(buf) size := binary.LittleEndian.Uint32(buf)
if size < 0x300 && size != 0 { if size <= 0xFFFF && size != 0 { // assume size is key len
return d.readRawKey(int64(size)) return d.readRawKey(int64(size))
} }
// try to use default static cipher // try to use default static cipher
@ -134,7 +132,7 @@ func (d *Decoder) readRawKey(rawKeyLen int64) error {
// clean suffix NULs // clean suffix NULs
rawKeyData = bytes.TrimRight(rawKeyData, "\x00") rawKeyData = bytes.TrimRight(rawKeyData, "\x00")
d.decodedKey, err = DecryptKey(rawKeyData) d.decodedKey, err = deriveKey(rawKeyData)
if err != nil { if err != nil {
return err return err
} }
@ -169,7 +167,7 @@ func (d *Decoder) readRawMetaQTag() error {
return errors.New("invalid raw meta data") return errors.New("invalid raw meta data")
} }
d.decodedKey, err = DecryptKey([]byte(items[0])) d.decodedKey, err = deriveKey([]byte(items[0]))
if err != nil { if err != nil {
return err return err
} }

Loading…
Cancel
Save