simple-privacy-tool/cmd/spt/hint.go

116 lines
1.7 KiB
Go

package spt
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"gitea.suyono.dev/suyono/simple-privacy-tool/privacy"
"github.com/spf13/cobra"
"io"
"os"
)
var (
ErrNotHint = errors.New("not a hint")
)
func SkipHint(b []byte, r io.Reader) (err error) {
if b[0] != 0xFF {
return ErrNotHint
}
hintLen := int(binary.LittleEndian.Uint16(b[1:3])) - 13 // 13 is hint minimum length, prevent overlapping with magic
if hintLen > 0 {
skip := make([]byte, hintLen)
var (
n, total int
)
for total < hintLen {
if n, err = r.Read(skip); err != nil {
return
}
total += n
}
}
return
}
func WriteHint(k privacy.KeyGen, w io.Writer) (err error) {
var (
b []byte
bb *bytes.Buffer
total int
n int
)
if b, err = k.MarshalJSON(); err != nil {
return
}
wb := make([]byte, 3)
wb[0] = 0xFF
if len(b) >= 13 {
binary.LittleEndian.PutUint16(wb[1:], uint16(len(b)))
} else {
binary.LittleEndian.PutUint16(wb[1:], uint16(13))
}
bb = bytes.NewBuffer(make([]byte, 0))
bb.Write(wb)
bb.Write(b)
if len(b) < 13 {
bb.Write(make([]byte, 13-len(b)))
}
b = bb.Bytes()
for total < len(b) {
if n, err = w.Write(b[total:]); err != nil {
return
}
total += n
}
return
}
func CmdReadHint(cmd *cobra.Command, args []string) (err error) {
var (
f *os.File
tb []byte
hLen int
)
if f, err = os.Open(args[0]); err != nil {
return
}
tb = make([]byte, 3)
if _, err = f.Read(tb); err != nil {
return
}
if tb[0] != 0xFF {
return ErrNotHint
}
hLen = int(binary.LittleEndian.Uint16(tb[1:]))
tb = make([]byte, hLen)
if _, err = f.Read(tb); err != nil {
return
}
if hLen == 13 {
for hLen > 0 {
if tb[hLen-1] != 0 {
break
}
hLen--
}
}
fmt.Println("hint:", string(tb[:hLen]))
return
}