首页 > 解决方案 > 如何有效地在 C# 中搜索特定 DWORD 值的第一个实例的原始字节数据?

问题描述

在 C/C++ 中,您可以O(n)使用指向缓冲区的指针并强制转换为 32 位数据类型来执行此操作,但在 C# 中给出byte[]IEnumerable<byte>以及int32如何有效地找到字节缓冲区中 DWORD 的第一个位置,理想情况下使用内置库方法?

我不想冒险进入不安全的代码,所以我当然可以搜索一个 4 元素字节子缓冲区。但是有没有更好的方法来利用我的 32 位长的搜索值?

琐碎的工作(伪ish):

int Find(IEnumerable<byte> buf, int val)
{
 byte d = val & 0xff, c = (val >>8) & 0xff, b = (val >>16) & 0xff, a = (val>>24) & 0xff;
 for(int i=0;i<buf.Length - 3;++i)
 {
  if(buf[i] == d && buf[i+1] == c && buf[i+2] == b && buf[i+3] == a)
   return i
 }
 return -1;
}

基本上想知道我是否可以将所有 4 个字节检查与单个 32 位检查结合起来。

标签: c#

解决方案


想知道我是否可以将所有 4 个字节检查与单个 32 位检查结合起来

并非没有违反对齐。您确实有一些选择是:

  1. 针对 4 种可能的对齐方式中的每一种(这将测试 32、24、16 或 8 位),与值的第一部分进行屏蔽的 32 位比较。成功后,您仍然需要针对剩余的位进行测试

  2. SIMD 比较在 16 个左右可能的相邻位置同时寻找针的第一个字节(或最独特的 - 我当然不想搜索,0x00因为会有超过 0.5% 的误报)。一旦你得到一个匹配,你还需要测试以下三个字节。


推荐阅读