Files

178 lines
3.1 KiB
Go
Raw Permalink Normal View History

2026-02-13 20:33:17 +00:00
package main
import (
"bytes"
"flag"
"fmt"
"io"
"math/rand"
"os"
"strings"
"time"
"github.com/marcinbor85/gohex"
)
var (
snLetters = []rune("ABCDEF0123456789")
snStock string = "BEE#-##-#######"
)
func main() {
stockSN := snBytes(snStock)
inhFile := flag.String("inh", "beeon-classic.hex", "input hex file")
insFile := flag.String("ins", "beeon-sn.txt", "input sn(s) file")
mkFile := flag.Bool("mk", false, "make-file : create random sn(s)")
mkPfx := flag.String("mk-p", "#-##", "make-file-prefix : string to add befoer random sn(s)")
mkAmount := flag.Int("mk-a", 1024, "make-file-amount : how many random sn(s) to make")
flag.Parse()
// make the sn(s) if being asked
if *mkFile {
rand.Seed(time.Now().UnixNano())
made := 0
failLimit := 20
randStrings := make([]string, *mkAmount)
for made < *mkAmount {
newS := strings.ToUpper(randSeq(7))
if contains(randStrings, newS) {
failLimit--
if failLimit < 0 {
break
}
continue
}
randStrings[made] = newS
made++
}
for _, v := range randStrings {
fmt.Printf("%s-%s\n", *mkPfx, v)
}
os.Exit(0)
}
// else patch hex and dump to stdout
sFile, err := os.OpenFile(*insFile, os.O_RDWR, 0666)
if err != nil {
panic(err)
}
defer sFile.Close()
line, err := popLine(sFile)
if err != nil {
panic(err)
}
if string(line) == "" {
panic(fmt.Errorf("no sn(s) %v", line))
}
newSN := snBytes(strings.Trim(string(line), "\n"))
hFile, err := os.Open(*inhFile)
if err != nil {
panic(err)
}
defer hFile.Close()
mem := gohex.NewMemory()
err = mem.ParseIntelHex(hFile)
if err != nil {
panic(err)
}
rawBytes := mem.ToBinary(0x0000, 8192, 0x00)
indexSN := bytes.Index(rawBytes, stockSN)
// patch in new SN +6 (BxExEx<>)
mem.SetBinary(uint32(indexSN+6), newSN)
mem.DumpIntelHex(os.Stdout, 16)
}
func randSeq(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = snLetters[rand.Intn(len(snLetters))]
}
return string(b)
}
func contains(a []string, x string) bool {
for _, n := range a {
if x == n {
return true
}
}
return false
}
func snBytes(i string) []byte {
bytes := make([]byte, len(i)*2)
r := []byte(i)
idx := 0
for _, rx := range r {
bytes[idx] = rx
idx = idx + 2
}
return bytes
}
func snString(i string) string {
o := "{ \"SN\": ["
r := []rune(i)
c := ""
for _, rx := range r {
o = fmt.Sprintf("%s%s-%d, 0", o, c, rx)
c = ", "
}
return o + " ] }"
}
func popLine(f *os.File) ([]byte, error) {
fi, err := f.Stat()
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(make([]byte, 0, fi.Size()))
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
_, err = io.Copy(buf, f)
if err != nil {
return nil, err
}
line, err := buf.ReadBytes('\n')
if err != nil && err != io.EOF {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
nw, err := io.Copy(f, buf)
if err != nil {
return nil, err
}
err = f.Truncate(nw)
if err != nil {
return nil, err
}
err = f.Sync()
if err != nil {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
return line, nil
}