Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// Randomly corrupts a file by writing a minimum amount of zeros.
package main
import (
"fmt"
"math/rand"
"os"
"time"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
seed = kingpin.Flag("seed", "Seed value for corruptor").Default(fmt.Sprintf("%v", time.Now().Unix())).Int64()
file = kingpin.Arg("file", "File to corrupt").Required().ExistingFile()
num_bytes = kingpin.Arg("numbytes", "Number of bytes to corrupt").Bytes()
max_span = kingpin.Flag("max-span", "Maximum contiguous bytes to corrupt").Bytes()
)
func main() {
kingpin.Parse()
rnd := rand.New(rand.NewSource(*seed))
filename := *file
st, err := os.Stat(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
f, err := os.OpenFile(filename, os.O_EXCL|os.O_RDWR, os.FileMode(0777))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer f.Close()
bytesCorrupted := int64(0)
bytesToCorrupt := int64(*num_bytes)
fmt.Println(bytesToCorrupt)
spans := 0
for 0 < bytesToCorrupt {
// Pick a start point in the file
startPoint := rnd.Int63n(st.Size())
// MaxSpan
maxSpan := rnd.Int63n(st.Size() - startPoint)
if bytesToCorrupt < maxSpan {
maxSpan = bytesToCorrupt
}
if st.Size() < (startPoint + maxSpan) {
maxSpan = st.Size() - startPoint
}
if maxSpan > int64(*max_span) {
maxSpan = int64(*max_span)
}
// Pick a range in the span range to corrupt
corruptSize := rnd.Int63n(maxSpan)
// Write zeroes over the corrupt range
if _, err := f.Seek(startPoint, os.SEEK_SET); err != nil {
fmt.Println(err)
os.Exit(1)
}
if _, err := f.Write(make([]byte, corruptSize, corruptSize)); err != nil {
fmt.Println(err)
os.Exit(1)
}
bytesToCorrupt -= corruptSize + 1
bytesCorrupted += corruptSize + 1
spans++
}
fmt.Printf("Zeroed out %d bytes in %d spans.\n", bytesCorrupted, spans)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment