You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效对[]byte进行16字节序列二分查找?避免[][]byte转换

直接在原始[]byte上实现高效二分查找,避免拆分循环

嘿,我完全懂你不想做那个慢循环的心情——其实根本没必要把整个字节切片拆分成[][]byte再做二分查找!我们可以直接在原始的buf上操作,跳过那个耗时的拆分步骤,同时实现高效的二分查找。

核心思路

因为你的每个IP条目都是固定的16字节,所以二分查找时,我们可以直接通过索引计算出当前要比较的条目在原始buf中的位置,不用提前把所有条目都切出来存到新切片里。这样既节省了内存分配,又省掉了遍历整个切片的时间。

修改后的代码

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "sort"
)

func main() {
    buf, err := ioutil.ReadFile("bin/test")
    if err != nil {
        fmt.Println(err)
        return
    }

    // 先检查buf长度是否是16的倍数(可选,但能避免越界)
    if len(buf)%16 != 0 {
        fmt.Println("文件格式错误:不是16字节条目的整数倍")
        return
    }

    // 假设n是你要查找的IP对应的16字节数据
    // 这里用一个示例值代替,你可以替换成实际的n.Bytes()
    target := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00}

    // 直接在原始buf上做二分查找
    itemCount := len(buf) / 16
    idx := sort.Search(itemCount, func(i int) bool {
        // 计算当前条目在buf中的切片范围
        current := buf[i*16 : i*16+16]
        // 比较当前条目和目标,返回是否大于等于目标(适配sort.Search的逻辑)
        return bytes.Compare(current, target) >= 0
    })

    // 检查是否找到匹配项
    if idx < itemCount {
        match := buf[idx*16 : idx*16+16]
        if bytes.Equal(match, target) {
            fmt.Printf("找到匹配的IP条目:%v\n", match)
        } else {
            fmt.Println("未找到目标IP")
        }
    } else {
        fmt.Println("未找到目标IP")
    }
}

关键细节说明

  • 跳过拆分循环:我们直接用i*16和i*16+16来定位每个16字节条目,完全不需要提前生成data切片,避免了大量的内存拷贝和append操作。
  • sort.Search的逻辑:这个函数会返回第一个满足func(i int) bool条件的索引,所以我们的比较逻辑是判断当前条目是否大于等于目标值,这样就能找到目标在有序切片中的位置(前提是你的文件中的IP条目是按顺序存储的,二分查找要求有序哦)。
  • 边界检查:添加了len(buf)%16 != 0的检查,能提前发现文件格式错误,避免后续切片越界。

这样修改后,你的代码效率会提升很多,尤其是当文件很大的时候,效果会非常明显!

内容的提问来源于stack exchange,提问作者user2626526

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:54:39