cli/algo/kgm/kgm.go

79 lines
1.6 KiB
Go
Raw Normal View History

2020-12-25 18:54:07 +00:00
package kgm
import (
"bytes"
"encoding/binary"
"errors"
2022-11-18 23:25:38 +00:00
2021-03-02 10:16:19 +00:00
"github.com/unlock-music/cli/algo/common"
2020-12-25 18:54:07 +00:00
)
var (
vprHeader = []byte{
0x05, 0x28, 0xBC, 0x96, 0xE9, 0xE4, 0x5A, 0x43,
0x91, 0xAA, 0xBD, 0xD0, 0x7A, 0xF5, 0x36, 0x31}
kgmHeader = []byte{
0x7C, 0xD5, 0x32, 0xEB, 0x86, 0x02, 0x7F, 0x4B,
0xA8, 0xAF, 0xA6, 0x8E, 0x0F, 0xFF, 0x99, 0x14}
ErrKgmMagicHeader = errors.New("kgm/vpr magic header not matched")
)
type Decoder struct {
2022-11-18 23:25:39 +00:00
file []byte
key []byte
maskFunc func(int) byte
audio []byte
2020-12-25 18:54:07 +00:00
}
2020-12-26 07:47:10 +00:00
func NewDecoder(file []byte) common.Decoder {
2020-12-25 18:54:07 +00:00
return &Decoder{
file: file,
}
}
2022-11-18 23:25:38 +00:00
func (d *Decoder) GetAudioData() []byte {
2020-12-25 18:54:07 +00:00
return d.audio
}
2022-11-18 23:25:38 +00:00
func (d *Decoder) GetAudioExt() string {
2021-05-23 11:58:23 +00:00
return "" // use sniffer
2020-12-25 18:54:07 +00:00
}
2022-11-18 23:25:38 +00:00
func (d *Decoder) GetMeta() common.Meta {
2020-12-25 18:54:07 +00:00
return nil
}
func (d *Decoder) Validate() error {
if bytes.Equal(kgmHeader, d.file[:len(kgmHeader)]) {
2022-11-18 23:25:39 +00:00
d.maskFunc = getKgmMask
2020-12-25 18:54:07 +00:00
} else if bytes.Equal(vprHeader, d.file[:len(vprHeader)]) {
2022-11-18 23:25:39 +00:00
d.maskFunc = getVprMask
2020-12-25 18:54:07 +00:00
} else {
return ErrKgmMagicHeader
}
d.key = d.file[0x1c:0x2c]
d.key = append(d.key, 0x00)
2021-05-23 11:58:23 +00:00
_ = d.file[0x2c:0x3c] //todo: key2
2020-12-25 18:54:07 +00:00
return nil
}
func (d *Decoder) Decode() error {
headerLen := binary.LittleEndian.Uint32(d.file[0x10:0x14])
2022-11-18 23:25:38 +00:00
d.audio = d.file[headerLen:]
2020-12-25 18:54:07 +00:00
2022-11-18 23:25:38 +00:00
for i := 0; i < len(d.audio); i++ {
2022-11-18 23:25:39 +00:00
med8 := d.audio[i] ^ d.key[i%17] ^ d.maskFunc(i)
d.audio[i] = med8 ^ (med8&0xf)<<4
2020-12-25 18:54:07 +00:00
}
2022-11-18 23:25:39 +00:00
2020-12-25 18:54:07 +00:00
return nil
}
2020-12-26 07:47:10 +00:00
func init() {
// Kugou
2021-11-11 15:43:20 +00:00
common.RegisterDecoder("kgm", false, NewDecoder)
common.RegisterDecoder("kgma", false, NewDecoder)
2020-12-26 07:47:10 +00:00
// Viper
2021-11-11 15:43:20 +00:00
common.RegisterDecoder("vpr", false, NewDecoder)
2020-12-26 07:47:10 +00:00
}