Home > Software design >  How do I remove offset from output of a binary file in Go?
How do I remove offset from output of a binary file in Go?

Time:04-16

I'm trying to only print out the data from a binary file in Go. None of the offset. Here's what I have for printing it out:

func readBinaryFile(filename string) {

    file, err := os.Open(filename)
    
    if err != nil {
        log.Fatal(err)
    }
    
    defer file.Close()

    reader := bufio.NewReader(file)

    buf := make([]byte, 256)

    for {
        _, err := reader.Read(buf)

        if err != nil {
            if err != io.EOF {
                fmt.Println(err)
            }
            break
        }
        fmt.Printf("%s", hex.Dump(buf))
    }

}

func main() {

    filename := os.Args[1]

    readBinaryFile(filename)

}

how do i remove all the offset it prints? I've tried a thousand things.

here's an example of output: example

CodePudding user response:

For a simple work-around, trim the offset from the dump output.

package main

import (
    "bufio"
    "encoding/hex"
    "io"
    "log"
    "os"
)

func dumpFile(filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer file.Close()
    rdr := bufio.NewReader(file)
    buf := make([]byte, 0, 16)
    for {
        n, rErr := io.ReadFull(rdr, buf[:cap(buf)])
        buf = buf[:n]
        if rErr == io.EOF {
            break
        }
        dump := hex.Dump(buf)[10:]
        _, wErr := io.WriteString(os.Stdout, dump)
        if wErr != nil {
            return wErr
        }
        if rErr != nil {
            if rErr == io.ErrUnexpectedEOF {
                break
            }
            return rErr
        }
    }
    return nil
}

func main() {
    filename := ""
    if len(os.Args) > 1 {
        filename = os.Args[1]
    }
    err := dumpFile(filename)
    if err != nil {
        log.Fatal(err)
    }
}

.

$ go run dump.go test.data
41 62 63 64 65 66 67 68  31 32 33 34 35 36 37 38  |Abcdefgh12345678|
58 59 5a 0a                                       |XYZ.|
$ 

CodePudding user response:

It's unclear from your question which output you are looking for:

  1. hex.Dump format without the offset, or
  2. Only print hex output

Assuming you only want to strip the offset from the dump, I would process the output:

package main

import (
    "encoding/hex"
    "fmt"
    "io"
    "os"
    "strings"
)   

func main() {
    buf, _ := io.ReadAll(os.Stdin)
    dump := hex.Dump(buf)
    fmt.Print(stripOffset(dump))
}   

func stripOffset(dump string) string {
    var b strings.Builder
    for dump != "" {
        var line string
        line, dump = next(dump, "\n")
        _, afterOffset := next(line, "  ")
        b.WriteString(afterOffset)
    }
    return b.String()
}

func next(s string, end string) (string, string) {
    if i := strings.Index(s, end); i >= 0 {
        split := i   len(end)
        return s[:split], s[split:]
    }   
    return s, ""
}   

Which can be used like:

$ echo some string to test the output | ./hex 
73 6f 6d 65 20 73 74 72  69 6e 67 20 74 6f 20 74  |some string to t|
65 73 74 20 74 68 65 20  6f 75 74 70 75 74 0a     |est the output.|

Alternatively, use hex.EncodeToString for just the hex output:

fmt.Println(hex.EncodeToString(buf))
736f6d6520737472696e6720746f207465737420746865206f75747075740a

Or format via fmt.Printf:

fmt.Printf("% 02x\n", buf)
73 6f 6d 65 20 73 74 72 69 6e 67 20 74 6f 20 74 65 73 74 20 74 68 65 20 6f 75 74 70 75 74 0a
  • Related