php - 在 PHP 中的二进制文件中搜索字节序列?

标签 php search optimization

我想使用 PHP 在二进制文件中查找特定的字节序列。我用十六进制表示这个序列,以避免输入太多的 0 和 1。要查找的序列是 0x4749524f。这是我现在提出的工作解决方案:

$mysequence = "4749524f";
$f = fopen($filename, "r") or die("Unable to open file!");
while(!feof($f)) {
    $seq = fread($f, 4);
    if(bin2hex($seq) == $mysequence) {
        echo "found!";
        break;
    }
    else if(!feof($f)) fseek($f, -3, SEEK_CUR);
}

算法的作用很简单:

  1. 读取 4 个字节
  2. 检查它们是否等于序列
  3. 如果它们相等 -> 找到了!停止执行。
  4. 如果它们不相等且 i 不在文件末尾,则返回文件中的 3 个字节并重复步骤 1。

为什么我要返回 3 Bytes?因为如果这是文件的内容:

0000 4749 524f 0000 01b0 0013

如果我不返回 3 字节,我将在第一次迭代时读取 0000 4749,在第二次迭代时读取 524f 000001b0 0013 在第三个,如你所见,我错过了序列。

问题:它慢得要命......应用程序将不得不处理最大 50MB 的文件,因此要花很长时间才能找到这个序列。

PHP 中是否有优化函数可以完成这项工作?有没有更快(不像我这样笨)的方法来做到这一点?

最佳答案

首先是你的$mysequence搜索时没有变化,所以你可以调用hex2bin($mysequence)一次并将其与 $seq 进行比较直接地。

至于真的更快,您可以尝试在大缓冲区中读取和搜索字符串。更大的缓冲区 => 更快的搜索,但需要更多的内存。快速代码草稿,它应该是什么样子:

$mysequence = "4749524f";
$searchBytes = hex2bin($mysequence);
$crossing = 1 - length($searchBytes); // - (length - 1); see below
$buf = ''; $buflen = 10000;
$f = fopen($filename, "r") or die("Unable to open file!");
while(!feof($f)) 
{
    $seq .= fread($f, $buflen);
    if(strpos($seq, $searchBytes) === false) // strict comparation here. zero can be returned!
    {
        // keep last n-1 bytes, because they can be beginning of required sequence
        $seq = substr($seq, $crossing);
    }
    else
    {
        echo "found!";
        break;
    }
}
unset($seq); // no need to keep this in memory any more

关于php - 在 PHP 中的二进制文件中搜索字节序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32487031/

相关文章:

PHP使用子数组值按字母顺序对数组进行排序

php - 关于如何在 linux 中与另一个 shell 交互使用 shell 的一些问题

php - 奇怪的 PDO 行为

php - Pimcore 时事通讯

eclipse - 如何清除 Eclipse 中的搜索历史?

c - 是否允许 C 编译器用另一种算法替换一种算法?

mysql - 优化数据库更新

mysql - Lucene/Sphinx/Mysql 的 100-1000+ 项搜索

sql - oracle中二进制字段(blob)的条件(如“like”)

algorithm - 聚类算法和 "extending"聚类以包括 N 个最近的邻居