C# 对 byte 数组进行模式搜索
本文告诉大家几个方法从 byte 数组找到对应的相同序列的数组
最简单的方法是进行数值判断,但是代码最少是使用Linq ,效率比较高是使用 Boyer-Moore 算法,下面就告诉大家几个算法的代码
判断数值
class ByteArrayRocks
{
public static IEnumerable<int> IndexOf(byte[] source, int start, byte[] pattern)
{
if (IsEmptyLocate(source, start, pattern))
{
yield break;
}
for (int i = start; i < source.Length; i++)
{
if (!IsMatch(source, i, pattern))
{
continue;
}
yield return i;
}
}
private static readonly int[] Empty = new int[0];
private static bool IsMatch(byte[] array, int position, byte[] candidate)
{
if (candidate.Length > (array.Length - position))
{
return false;
}
for (int i = 0; i < candidate.Length; i++)
{
if (array[position + i] != candidate[i])
{
return false;
}
}
return true;
}
private static bool IsEmptyLocate(byte[] array, int start, byte[] candidate)
{
return array == null
|| candidate == null
|| array.Length == 0
|| array.Length < start
|| candidate.Length == 0
|| candidate.Length + start > array.Length;
}
}
这是最简单的方法,参见 https://stackoverflow.com/a/283648/6116637
linq
这个方法的代码最少
class LinqArraySearch
{
public static IEnumerable<int> IndexOf(byte[] source, int start, byte[] pattern)
{
for (int i = start; i < source.Length; i++)
{
if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern))
{
yield return i;
}
}
}
}
Boyer-Moore-Horspool 搜索
这是最快的方法
class BoyerMooreHorspool
{
public static IEnumerable<long> IndexesOf(byte[] source, int start, byte[] pattern)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (pattern == null)
{
throw new ArgumentNullException(nameof(pattern));
}
long valueLength = source.LongLength;
long patternLength = pattern.LongLength;
if ((valueLength == 0) || (patternLength == 0) || (patternLength > valueLength))
{
yield break;
}
var badCharacters = new long[256];
for (var i = 0; i < 256; i++)
{
badCharacters[i] = patternLength;
}
var lastPatternByte = patternLength - 1;
for (long i = 0; i < lastPatternByte; i++)
{
badCharacters[pattern[i]] = lastPatternByte - i;
}
long index = start;
while (index <= valueLength - patternLength)
{
for (var i = lastPatternByte; source[index + i] == pattern[i]; i--)
{
if (i == 0)
{
yield return index;
break;
}
}
index += badCharacters[source[index + lastPatternByte]];
}
}
}
参见:https://stackoverflow.com/q/16252518/6116637
测试了三个方法的性能,请看下面
BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.1.202
[Host] : .NET Core 2.0.9 (CoreCLR 4.6.26614.01, CoreFX 4.6.26614.01), 64bit RyuJIT
DefaultJob : .NET Core 2.0.9 (CoreCLR 4.6.26614.01, CoreFX 4.6.26614.01), 64bit RyuJIT
| Method | Mean | Error | StdDev |
|---|---|---|---|
| Linq | 13,332.8 us | 251.782 us | 466.694 us |
| ByteArrayRocks | 371.3 us | 7.327 us | 14.462 us |
| BoyerMooreHorspool | 108.3 us | 1.153 us | 1.079 us |
其他方法请看下面
使用不安全代码的 Boyer Moore 算法 C# High Performance Boyer Moore Byte Array Search Algorithm
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
C# 对 byte 数组进行模式搜索的更多相关文章
- go语言:多个[]byte数组合并成一个[]byte
场景:在开发中,要将多个[]byte数组合并成一个[]byte,初步实现思路如下: 1.获取多个[]byte长度 2.构造一个二维码数组 3.循环将[]byte拷贝到二维数组中 package gst ...
- byte数组和File,InputStream互转
1.将File.FileInputStream 转换为byte数组: File file = new File("file.txt"); InputStream input = n ...
- C# byte数组与Image的相互转换
功能需求: 1.把一张图片(png bmp jpeg bmp gif)转换为byte数组存放到数据库. 2.把从数据库读取的byte数组转换为Image对象,赋值给相应的控件显示. 3.从图片byte ...
- 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化
序列化在高性能网络编程.分布式系统开发中是举足轻重的之前有用过Java序列化.ProtocolBuffer等,在这篇文章这里中简单分析序列化后的byte数组观察各种序列化的差异与性能,这里主要分析Ja ...
- 字符串与byte数组转换
string weclome=""; byte[] data = new byte[1024]; //字符串转byte数组 data = Encoding.ASCII.GetByt ...
- C# 将文件转化成byte[]数组
/// <summary> /// 将文件转换成byte[] 数组 /// </summary> /// <param name="fileUrl"& ...
- Java 文件和byte数组转换
/** * 获得指定文件的byte数组 */ private byte[] getBytes(String filePath){ byte[] buffer = null; try { File fi ...
- InputStream,BufferedImage与byte数组之间的转换
需要获取网络的一张图片,但是某种需要,要把获取的这段流输入换为BufferedImage流,有的地方还需要转换为byte[]. 获得图片地址,获得了一个图片输入流,例如: Url img = n ...
- php byte数组与字符串转换类
<?php /** * byte数组与字符串转化类 * @author ZT */ class Bytes { /** * 转换一个string字符串为byte数组 * @param $str ...
随机推荐
- thrift python安装
http://thrift.apache.org/download/ tar -zxvf thrift-0.11.0.tar.gz cd thrift-0.11.0 ./configure --pre ...
- Linux安装mongoDB步骤和方法
Linux安装mongoDB步骤和方法 下载mongoDB数据库 mongodb-linux-x86_64-3.0.15.tgz 存放到linux文件夹中 ftp软件直接拖上去 解压文件夹(解压后,会 ...
- [转]GDB调试基础
一.gdb常用命令: 命令 描述 backtrace(或bt) 查看各级函数调用及参数 finish 连续运行到当前函数返回为止,然后停下来等待命令 frame(或f) 帧编号 选择栈帧 info(或 ...
- RedHat6.2离线安装vncserver
准备安装包 tigervnc-server-1.1.0-5.el6_4.1.x86_64.rpm pixman-0.32.8-1.el6.x86_64.rpm pixman-devel-0.32.8- ...
- hdu1730 尼姆博弈
抽象一下把距离当做石子个数.虽然在这里石子个数可以增加,但是不管怎么增加,不会影响结果,因为你增加了,必须会有减少的. 所以类似取石子,观察平衡状态,如果(x2-x1-1)^...==0,必输. wa ...
- 源码篇:MBProgressHUD
源码来源:点此 版本:0.9.1 MBProgressHUD是一个显示HUD窗口的第三方类库,用于在执行一些后台任务时,在程序中显示一个表示进度的loading视图和两个可选的文本提示的HUD窗口.我 ...
- 洛谷3067 BZOJ 2679题解(折半搜索)
传送门 BZOJ传送门(权限题) 看到n小于20,就可以想到搜索 所有的数要么在集合a中,要么在集合b中,要么都不在 可是3^n复杂度会炸,我们考虑优化 可以利用折半搜索,将前面一半的所有可能情况与后 ...
- 《DL/T 1476-2015 电力安全工器具预防性试验规程》中的样品名称及试验项目
- ubuntu18.10 安装pycurl
sudo apt-get install libcurl3 sudo apt-get install libcurl4-openssl-devsudo apt-get install python3 ...
- Flask学习之十三 日期和时间
英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xiii-dates-and-times 中文翻译地址: ...