go - 高效二分查找 []byte 而不是 [][]byte

标签 go binary binary-search

TL;DR I need to efficiently binary search a byte slice for a sequence of bytes.

相关:byte[] array pattern search

我有一个 16 字节 IP 地址的二进制文件,我想对其进行二进制搜索。我使用 Packr 将此文件嵌入到 go Binary 中,它将提供文件数据的 []byte

这意味着我必须循环 []byte 来创建 [][]byte 来搜索 16 个字节而不是 1 个字节。这个循环效率不高,我正在寻找一种方法来避免它。

我在下面制作了一个最小的示例,没有使用 Packr。

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    // Get our file. It is a file with many 16-byte form IP.
    // head -c 32 bin/test | xxd
    // 00000000: 0100 0000 0000 0000 0000 0000 0000 0000  ................
    // 00000010: 0000 0000 0000 0000 1800 0000 0000 0000  ................

    buf, err := ioutil.ReadFile("bin/test")

    if err != nil {
        fmt.Println(err)
    }

    // This is too slow :-(
    // How could this loop be replaced by some additional logic in the binary search below
    data := [][]byte{}
    for i := 0; i < len(buf); i += 16 {
        data = append(data, buf[i:i+16])
    }

    i := sort.Search(len(data), func(i int) bool {
        fmt.Println(len(data[i]), len(n.Bytes()))
        return bytes.Compare(data[i], n.Bytes()) < 1
    })

    if i < len(data) {
        fmt.Println(data[i])
    } else {
        fmt.Println("Not found")
    }
}


最佳答案

使用以下代码在包含排序 IP 地址的 byte slice 中二分查找 16 字节 IP 地址。

func search16(haystack, needle []byte) int {
    return 16 * sort.Search(len(haystack)/16, 
       func(i int) bool { return bytes.Compare(haystack[i*16:(i+1)*16], needle) >= 0 })
}

sort.Search 看到的索引是字节偏移量除以 16。sort.Search 的结果乘以 16 得到字节偏移量。

关于go - 高效二分查找 []byte 而不是 [][]byte,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58458933/

相关文章:

go - `go mod tidy` 提示bazel生成的protobuf包丢失

Ruby:拆分二进制数据

python - 如何在 Python 中解码二进制编码的邮件消息?

java - 制作二叉搜索树

go - 为什么 go 模块版本有时在 go.sum 中需要 2 行

c - 在 C 语言中使用 Go 的限制

golang mqtt 发布和订阅

binary - 我的 IEEE 754 浮点表示有什么问题?

java - 二分查找算法检查数组中是否包含整数