Read string from binary

Hi, all!
I am trying to read my binary file to grab string from different positions:
like this this

func main() {
f, err := os.Open("binaryfile.bin")
if err != nil {
	log.Fatalln(err)
}
defer f.Close()
var val float64
err = binary.Read(f, binary.LittleEndian, &val)
if err != nil {
	log.Fatalln(err)
}
fmt.Println(pi)}

I’m completely lost

What you have looks like it will read the first 8 bytes of a file and interpret it as a float64. Based on your screenshot, it looks like you actually want the data at offset 14 (if I’m counting the dots correctly on my phone screen right now). Before you call binary.Read, you should call f.Seek to set the position of the file to the offset of the beginning of the data you want to read, and then call binary.Read.

You’ll need to do the same seeking for the strings you want, too, but you won’t need binary.Read, you could just slice the bytes that you read and then convert to a string after. Are the strings always the same length or do you need to inspect the file at some other offset to determine the string’s length?

Thank you for answer,
My idea is to find the first ip and read the data after that because the length between is the same like this pastebin hex

I’am beginner and newbie with Golang

my new code

func main() {
	file, err := os.Open("data.bin")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	o2, err := file.Seek(110, io.SeekCurrent) <---- First occurrence 
	byteSlice := make([]byte, 32)
	bytesRead, err := file.Read(byteSlice)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("IP: %s\n", byteSlice)
}

Is this working for you or do you still need help?

Its working but my code its not clean :slightly_frowning_face:

    file, err := os.Open("data.bin")
check(err)
defer file.Close()

o1, err := file.Seek(110, 0)  <--- first position
check(err)
_ip := make([]byte, 15)
ipRead, err := file.Read(_ip)
clean_ip := strings.ReplaceAll(string(_ip[:]), " ", " ")

o2, err := file.Seek(21, io.SeekCurrent)
check(err)
_user := make([]byte, 15)
userRead, err := file.Read(_user)
clean_user := strings.ReplaceAll(string(_user[:]), " ", " ")

o3, err := file.Seek(532, 0)  <---- Second position
check(err)
_pwd := make([]byte, 20)
pwdRead, err := file.Read(_pwd)
clean_pwd := strings.ReplaceAll(string(_pwd[:]), " ", " ")

You could put the repetitive parts into a function: https://play.golang.org/p/iflkAKaXbuh

I’m not sure what you’re going for with strings.ReplaceAll(string(_ip[:]), " ", " "): This replaces all the spaces with spaces, so essentially a no-op.

My guess, from looking at the file dump, is that they are C strings. Therefore, it’s an attempt to replace NUL by space.

A better solution would be a CToGoString function:

package main

import "fmt"

func CToGoString(c []byte) string {
	n := -1
	for i, b := range c {
		if b == 0 {
			break
		}
		n = i
	}
	return string(c[:n+1])
}

func main() {
	// IPV4
	c := []byte("\x34\x31\x2E\x31\x39\x31\x2E\x39\x37\x2E\x36\x32\x00\x00\x00")
	fmt.Printf("%d %q\n", len(c), c)
	g := CToGoString(c)
	fmt.Printf("%d %q\n", len(g), g)
	c = []byte("1.1.1.1\x00\x00\x00\x00\x00\x00\x00\x00")
	fmt.Printf("%d %q\n", len(c), c)
	g = CToGoString(c)
	fmt.Printf("%d %q\n", len(g), g)
	c = []byte("111.111.111.111")
	fmt.Printf("%d %q\n", len(c), c)
	g = CToGoString(c)
	fmt.Printf("%d %q\n", len(g), g)
	c = make([]byte, 15)
	fmt.Printf("%d %q\n", len(c), c)
	g = CToGoString(c)
	fmt.Printf("%d %q\n", len(g), g)
}
15 "41.191.97.62\x00\x00\x00"
12 "41.191.97.62"
15 "1.1.1.1\x00\x00\x00\x00\x00\x00\x00\x00"
7 "1.1.1.1"
15 "111.111.111.111"
15 "111.111.111.111"
15 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
0 ""

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.