1
0
forked from um/cli
cli/algo/kgm/kgm.go

62 lines
1.2 KiB
Go

package kgm
import (
"fmt"
"io"
"github.com/unlock-music/cli/algo/common"
)
type Decoder struct {
header header
cipher common.StreamDecoder
rd io.ReadSeeker
offset int
}
func NewDecoder(rd io.ReadSeeker) common.Decoder {
return &Decoder{rd: rd}
}
var kgmCryptoInitializers = map[uint32]func(header *header) (common.StreamDecoder, error){
3: newKgmCryptoV3,
}
func (d *Decoder) Validate() error {
if err := d.header.FromFile(d.rd); err != nil {
return err
}
// TODO; validate crypto version
initializer, ok := kgmCryptoInitializers[d.header.CryptoVersion]
if !ok {
return fmt.Errorf("kgm: unsupported crypto version %d", d.header.CryptoVersion)
}
var err error
d.cipher, err = initializer(&d.header)
if err != nil {
return fmt.Errorf("kgm: failed to initialize crypto: %w", err)
}
return nil
}
func (d *Decoder) Read(buf []byte) (int, error) {
n, err := d.rd.Read(buf)
if n > 0 {
d.cipher.Decrypt(buf[:n], d.offset)
d.offset += n
}
return n, err
}
func init() {
// Kugou
common.RegisterDecoder("kgm", false, NewDecoder)
common.RegisterDecoder("kgma", false, NewDecoder)
// Viper
common.RegisterDecoder("vpr", false, NewDecoder)
}