package main import ( "bufio" "encoding/hex" "fmt" "log" "os" "strings" ) func main() { file, err := os.Open("save.txt") if err != nil { log.Fatalf("Failed to open file: %s", err) } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() decodeBeacon(line) } } func decodeBeacon(beacon string) { beacon = strings.TrimSpace(beacon) if beacon == "" { return } // convert to bytes for faster operations b, err := hex.DecodeString(beacon) if err != nil { fmt.Println("invalid line: ", beacon) return } // remove flag bytes - they hold no structural information if len(b) > 1 && b[1] == 0x01 { l := int(b[0]) if 1+l <= len(b) { b = b[1+l:] } } adBlockIndeces := parseADFast(b) for _, r := range adBlockIndeces { ad := b[r[0]:r[1]] if len(ad) >= 4 && ad[1] == 0x16 && ad[2] == 0xAA && ad[3] == 0xFE { // fmt.Println("Eddystone:", hex.EncodeToString(b)) return } if len(ad) >= 7 && ad[1] == 0xFF && ad[2] == 0x4C && ad[3] == 0x00 && ad[4] == 0x02 && ad[5] == 0x15 { // fmt.Println("iBeacon:", hex.EncodeToString(b)) return } } fmt.Println(hex.EncodeToString(b)) } func parseADFast(b []byte) [][2]int { var res [][2]int i := 0 for i < len(b) { l := int(b[i]) if l == 0 || i+1+l > len(b) { break } res = append(res, [2]int{i, i + 1 + l}) i += 1 + l } return res }