Files
bricker/main.go
2024-08-31 15:35:33 +02:00

114 lines
2.6 KiB
Go

package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"sync"
"time"
"golang.org/x/exp/rand"
)
var Error *log.Logger
var Warning *log.Logger
func init() {
log.SetFlags(log.Lmicroseconds | log.Lshortfile)
logger := io.MultiWriter(os.Stdout)
log.SetOutput(logger)
Error = log.New(io.MultiWriter(os.Stderr, os.Stdout),
fmt.Sprintf("%sERROR:%s ", "\033[0;101m", "\033[0m"),
log.Lmicroseconds|log.Lshortfile)
Warning = log.New(io.MultiWriter(os.Stdout),
fmt.Sprintf("%sWarning:%s ", "\033[0;93m", "\033[0m"),
log.Lmicroseconds|log.Lshortfile)
}
func main() {
percent := flag.Int("p", 20, "Percent to mangle")
w := flag.Int("w", 8, "Workers")
flag.Parse()
workers := make(chan struct{}, *w)
wg := sync.WaitGroup{}
log.Printf("Corrupting %d%% of each input file", *percent)
log.Printf("Using %d workers", *w)
for _, file := range flag.Args() {
wg.Add(1)
workers <- struct{}{}
go func(file string) {
defer wg.Done()
defer func() { <-workers }()
log.Printf("Corrupting %s", file)
filehandle, err := os.OpenFile(file, os.O_RDWR, 0644)
if err != nil {
Error.Printf("Error opening %v: %v", file, err)
return
}
defer filehandle.Close()
// data, err := io.ReadAll(filehandle)
// if err != nil {
// Error.Printf("Error reading %v: %v", file, err)
// return
// }
// log.Printf("Read %d bytes from %s", len(data), file)
// filehandle.Seek(0, io.SeekStart)
info, err := os.Stat(file)
if err != nil {
Error.Printf("Error getting file info for %v: %v", file, err)
return
}
filesize := info.Size()
log.Printf("File size is %d bytes", filesize)
toCorrupt := int64(float32(filesize) * (float32(*percent) / 100))
indicesToCorrupt := selectRandomIndices(filesize, toCorrupt)
log.Printf("Corrupting %d bytes in %s", toCorrupt, file)
for _, index := range indicesToCorrupt {
rbyte := byte(rand.Intn(256))
filehandle.Seek(int64(index), io.SeekStart)
filehandle.Write([]byte{rbyte})
}
log.Printf("Corrupted %d bytes in %s", toCorrupt, file)
// n, err := filehandle.Write(data)
// if err != nil {
// Error.Printf("Error writing %v: %v", file, err)
// return
// }
// log.Printf("Wrote %d bytes to %s", n, file)
}(file)
}
wg.Wait()
}
func selectRandomIndices(size, n int64) []int64 {
indices := make([]int64, n)
for i := range indices {
indices[i] = int64(i)
}
rand.Seed(uint64(time.Now().UnixNano()))
for i := n; i < size; i++ {
r := rand.Int63n(i + 1)
if r < n {
indices[r] = i
}
}
return indices
}