refactor: split into subpackages and add AEAD/options/stream APIs with comprehensive tests
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func VicqueEncodeV1(srcdata []byte, key string) []byte {
|
||||
var keys []int
|
||||
var randCode [2]byte
|
||||
_, _ = io.ReadFull(rand.Reader, randCode[:])
|
||||
|
||||
data := make([]byte, len(srcdata))
|
||||
copy(data, srcdata)
|
||||
|
||||
randCode1 := int(randCode[0])
|
||||
randCode2 := int(randCode[1])
|
||||
keys = append(keys, len(key)+randCode1)
|
||||
for _, v := range key {
|
||||
keys = append(keys, int(byte(v))+randCode1-randCode2)
|
||||
}
|
||||
|
||||
lens := len(data)
|
||||
lenkey := len(keys)
|
||||
for k, v := range data {
|
||||
if k == lens/2 {
|
||||
break
|
||||
}
|
||||
nv := int(v)
|
||||
t := 0
|
||||
if k%2 == 0 {
|
||||
nv += keys[k%lenkey]
|
||||
if nv > 255 {
|
||||
nv -= 256
|
||||
}
|
||||
t = int(data[lens-1-k])
|
||||
t += keys[k%lenkey]
|
||||
if t > 255 {
|
||||
t -= 256
|
||||
}
|
||||
} else {
|
||||
nv -= keys[k%lenkey]
|
||||
if nv < 0 {
|
||||
nv += 256
|
||||
}
|
||||
t = int(data[lens-1-k])
|
||||
t -= keys[k%lenkey]
|
||||
if t < 0 {
|
||||
t += 256
|
||||
}
|
||||
}
|
||||
data[k] = byte(t)
|
||||
data[lens-1-k] = byte(nv)
|
||||
}
|
||||
data = append(data, randCode[0], randCode[1])
|
||||
return data
|
||||
}
|
||||
|
||||
func VicqueDecodeV1(srcdata []byte, key string) []byte {
|
||||
if len(srcdata) < 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
data := make([]byte, len(srcdata))
|
||||
copy(data, srcdata)
|
||||
lens := len(data)
|
||||
|
||||
randCode1 := int(data[lens-2])
|
||||
randCode2 := int(data[lens-1])
|
||||
|
||||
keys := []int{len(key) + randCode1}
|
||||
for _, v := range key {
|
||||
keys = append(keys, int(byte(v))+randCode1-randCode2)
|
||||
}
|
||||
|
||||
lenkey := len(keys)
|
||||
lens -= 2
|
||||
for k, v := range data {
|
||||
if k == lens/2 {
|
||||
break
|
||||
}
|
||||
nv := int(v)
|
||||
t := 0
|
||||
if k%2 == 0 {
|
||||
nv -= keys[k%lenkey]
|
||||
if nv < 0 {
|
||||
nv += 256
|
||||
}
|
||||
t = int(data[lens-1-k])
|
||||
t -= keys[k%lenkey]
|
||||
if t < 0 {
|
||||
t += 256
|
||||
}
|
||||
} else {
|
||||
nv += keys[k%lenkey]
|
||||
if nv > 255 {
|
||||
nv -= 256
|
||||
}
|
||||
t = int(data[lens-1-k])
|
||||
t += keys[k%lenkey]
|
||||
if t > 255 {
|
||||
t -= 256
|
||||
}
|
||||
}
|
||||
data[k] = byte(t)
|
||||
data[lens-1-k] = byte(nv)
|
||||
}
|
||||
return data[:lens]
|
||||
}
|
||||
|
||||
func VicqueEncodeV1File(src, dst, pwd string, progress func(float64)) error {
|
||||
fpsrc, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fpsrc.Close()
|
||||
|
||||
stat, err := fpsrc.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fpdst, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fpdst.Close()
|
||||
|
||||
var sum int64
|
||||
buf := make([]byte, 1024*1024)
|
||||
for {
|
||||
n, readErr := fpsrc.Read(buf)
|
||||
if n > 0 {
|
||||
sum += int64(n)
|
||||
data := VicqueEncodeV1(buf[:n], pwd)
|
||||
if _, err := fpdst.Write(data); err != nil {
|
||||
return err
|
||||
}
|
||||
reportProgress(progress, sum, stat.Size())
|
||||
}
|
||||
if readErr != nil {
|
||||
if readErr == io.EOF {
|
||||
break
|
||||
}
|
||||
return readErr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func VicqueDecodeV1File(src, dst, pwd string, progress func(float64)) error {
|
||||
fpsrc, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fpsrc.Close()
|
||||
|
||||
stat, err := fpsrc.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fpdst, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fpdst.Close()
|
||||
|
||||
var sum int64
|
||||
buf := make([]byte, 1024*1024+2)
|
||||
for {
|
||||
n, readErr := fpsrc.Read(buf)
|
||||
if n > 0 {
|
||||
sum += int64(n)
|
||||
data := VicqueDecodeV1(buf[:n], pwd)
|
||||
if _, err := fpdst.Write(data); err != nil {
|
||||
return err
|
||||
}
|
||||
reportProgress(progress, sum, stat.Size())
|
||||
}
|
||||
if readErr != nil {
|
||||
if readErr == io.EOF {
|
||||
break
|
||||
}
|
||||
return readErr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reportProgress(progress func(float64), current, total int64) {
|
||||
if progress == nil {
|
||||
return
|
||||
}
|
||||
if total <= 0 {
|
||||
progress(100)
|
||||
return
|
||||
}
|
||||
progress(float64(current) / float64(total) * 100)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVicqueRoundTrip(t *testing.T) {
|
||||
plain := []byte("legacy-vicque-roundtrip")
|
||||
enc := VicqueEncodeV1(plain, "secret")
|
||||
dec := VicqueDecodeV1(enc, "secret")
|
||||
if !bytes.Equal(dec, plain) {
|
||||
t.Fatalf("vicque roundtrip mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVicqueFileRoundTrip(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
src := filepath.Join(dir, "src.bin")
|
||||
enc := filepath.Join(dir, "src.enc")
|
||||
out := filepath.Join(dir, "src.out")
|
||||
plain := []byte("legacy-vicque-file-roundtrip")
|
||||
if err := os.WriteFile(src, plain, 0o644); err != nil {
|
||||
t.Fatalf("WriteFile failed: %v", err)
|
||||
}
|
||||
if err := VicqueEncodeV1File(src, enc, "pwd", nil); err != nil {
|
||||
t.Fatalf("VicqueEncodeV1File failed: %v", err)
|
||||
}
|
||||
if err := VicqueDecodeV1File(enc, out, "pwd", nil); err != nil {
|
||||
t.Fatalf("VicqueDecodeV1File failed: %v", err)
|
||||
}
|
||||
got, err := os.ReadFile(out)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile failed: %v", err)
|
||||
}
|
||||
if !bytes.Equal(got, plain) {
|
||||
t.Fatalf("vicque file roundtrip mismatch")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user