问题
I am trying to read a binary file to grab string from different positions; read {IP,login,pwd} my idea is to find the first ip and read the data after that because the length between is the same like this :
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000060 5F 00 00 00 00 11 E0 BB 5F 00 00 00 00 01 34 31 _.....à»_.....40
00000070 2E 31 39 31 2E 39 37 2E 36 32 00 00 00 00 00 00 .091.17.02......
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090 00 00 73 75 70 70 6F 72 74 00 00 00 00 00 00 00 ..support.......
000000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000210 00 00 00 00 31 71 61 7A 40 57 53 58 00 00 00 00 ....1qaz@WSX....
00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
My Go code
import (
"io"
"log"
"os"
)
func main() {
file, err := os.Open("data")
if err != nil {
log.Fatal(err)
}
defer file.Close()
o2, err := file.Seek(110, io.SeekCurrent) <---- find first occurrence
byteSlice := make([]byte, 32)
bytesRead, err := file.Read(byteSlice)
if err != nil {
log.Fatal(err)
}
log.Printf("IP: %s\n", byteSlice)
}
how to find all occurrences { ip, login, pwd } after finding ip, with my code I can just find the first one (ip) 32bits.
回答1:
One approach would be to iterate the file. Essentially you could reimplement
the strings
program. It would be similar to using bufio#Scanner.Scan,
but you would need to iterate on null bytes instead of newlines. You can use
bufio#Scanner.Split, and Go even offers some premade functions.
However the premade functions are ScanBytes, ScanLines, ScanRunes and
ScanWords, none of which really help in this case. I took a look at ScanLines,
but it returns empty lines too. And we definitely dont want thousands of returns
on repeat null bytes. So best chance is with ScanWords. I tossed out the
Unicode stuff as we are dealing with binary data. Then I basically changed
isSpace
to "is null byte". Here is the result:
package main
func ScanNull(y []byte, b bool) (int, []byte, error) {
n1 := 0
for n1 < len(y) {
if y[n1] != '\x00' {
break
}
n1++
}
for n2 := n1; n2 < len(y); n2++ {
if y[n2] == '\x00' {
return n2 + 1, y[n1:n2], nil
}
}
if b && len(y) > n1 {
return len(y), y[n1:], nil
}
return n1, nil, nil
}
and in use:
package main
import (
"bufio"
"strings"
)
func main() {
const input = "March\x00April\x00May\x00\x00June"
scanner := bufio.NewScanner(strings.NewReader(input))
scanner.Split(ScanNull)
for scanner.Scan() {
println(scanner.Text())
}
}
回答2:
Thank you for help,
I use file.Seek(x,0) like this code:
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[:]), " ", " ")
Its working but not clean
来源:https://stackoverflow.com/questions/65112561/extract-text-from-x-pos-binary-file