我想创建一种方法来扫描特定数组的字节数组 我已经完成了这个,但我还想要其他东西,我想扩展它 因此它可以通过用256(0xff)替换它们来扫描一些索引是未知的数组 例如 如果我有这样的数组[1,2,3,4,5,6,7,8,9,20,30,50] 通常情况下,我可以搜索[5,6,7],它会索引[4]因为那是5开始的地方 我希望能够搜索[5,256,7]之类的东西,这意味着如果我不知道 256的实际值,我仍然会得到正确的答案
我的解决方案是抓取一个256/512字节的块,使用for循环读取一个x字节的块(在这种情况下,3个字节),并用字节中相应索引的相应值替换256读
这是我试过的代码,但它无法正常工作
p.s,这个方法是为了扫描真正大的数组,这就是为什么有一些大的值
public long arraySearch(byte[] scanFor, long startIndex, long endIndex)
{
if (scanFor.Length == 0 || startIndex == 0 || endIndex == 0 || endIndex
<= startIndex - scanFor.Length) return 0;
long tempStart = startAddress;
long foundIndex = 0;
long tmpAd = 0;
long maxChunk = endIndex - startIndex;
float parts = maxChunk / 256;
int x = 0;
byte[] tmp = new byte[scanFor.Length];
byte[] buf = new byte[256];
for (x = 0; x < parts; x++)
{
//the 'byte[] ReadArray(int64 index,int length)' method returns a byte array
(byte[]) at the given index of the specified size
buf = ReadArray(tempStart, 256);
for (int i = 0; i < 256; i++)
{
if (buf[i] == scanFor[0])
{
tmp = ReadArray(tempStart + i, scanFor.Length);
for (int iii = 0; iii < scanFor.Length; iii++)
{
if (scanFor[iii] == 0xff) scanFor[iii] = tmp[iii];
}
tmpAd = tempStart + i;
//the 'ByteArrayCompare' method compares all elements of an array and
returns true if all are equal
if (ByteArrayCompare(tmp, scanFor))
{
foundIndex = tmpAd;
break;
}
}
}
tempStart += 256;
}
return foundIndex;
}
答案 0 :(得分:0)
我觉得你的代码非常令人困惑,所以我无法告诉你它的错误,但我可以试着用你的尝试为你解释一个有效的解决方案。
首先,我创建了一些帮助程序来模拟你的环境 - 告诉我,我是否理解了错误(这些部分只是为了简化我的事情):
private static readonly byte [] FirstPart = Enumerable.Repeat (1, 250).Select (i => (byte) i).ToArray ();
private static readonly byte [] SecondPart = Enumerable.Range (1, 250).Select (i => (byte) i).ToArray ();
private static readonly byte [] ThirdPart = Enumerable.Range (0, 250).Select (i => (byte) i).ToArray ();
private static readonly byte [] FourthPart = Enumerable.Repeat (1, 500).Select (i => (byte) i).ToArray ();
private static readonly byte [] WholeArray =
new [] {FirstPart, SecondPart, ThirdPart, FourthPart}.SelectMany (bytes => bytes).ToArray ();
private static byte [] ReadArray (long index, int length) =>
WholeArray.Where ((b, i) => i >= index && i < index + length).ToArray ();
然后这就是我提出的ArraySearch
的实现 - 我在评论中解释过,如果有什么不清楚的地方,请随时问:
public static long ArraySearch (byte [] scanFor, long startIndex, long endIndex)
{
if (startIndex < 0 ||
endIndex < startIndex ||
scanFor.Length > endIndex - startIndex) //Check wether the parameters are valid
return -1;
if (scanFor.Length == 0) //If the scanFor is empty, we must return 0 directly,
//as an IndexOutOfRange exception would be caused otherwise
return 0;
var partsCount = (endIndex - startIndex) / 256; //The number of parts to scan
long tempFoundIndex = -1; //The found index, that is later going to be returned
for (var i = 0; i < partsCount; i++) //We iterate through the parts
//to find an item in those parts which matches the first item of the array we're searching for
{
var start = i * 256 + startIndex; //This is the startIndex of the current part
if (start > endIndex) //If the start index is already bigger than the endIndex, we can directly break,
//because we won't find the array in the specified range anymore
break;
var part = ReadArray (start, 256); //This is the part we're currently scanning
for (var j = 0; j < part.Length && start + j <= endIndex; j++) //Now we're iterating this part
//to find the item which matches the first item of the array we're searching for
if (scanFor [0] == 0xFF || part [j] == scanFor [0]) //If we found such an item,
//we want to check all following items, wether they match the to search array as well
{
var arrayCheckFailed = false; //This indicates wether it already failed,
//so that it doesn't continue to search
var tempScanForIndex = 0; //This is the index of the item from ScanFor we're currently checking
tempFoundIndex = start + j; //This is the starting index we found
//and we later want to return, if all items match
for (var i2 = i; i2 < partsCount && !arrayCheckFailed; i2++)
//So we're once again iterating through the parts (beginning from the current part)
//to check the items from the parts
{
var start2 = i2 * 256 + startIndex; //This is once again the startIndex of the current part
if (start2 > endIndex) //see above
break;
var part2 = ReadArray (start2, 256);//TODO RENAME
for (var j2 = i2 == i ? j : 0; j2 < part2.Length && start2 + j2 <= endIndex; j2++)
if (scanFor [tempScanForIndex] == 0xFF || part2 [j2] == scanFor [tempScanForIndex])
{
tempScanForIndex++; //If the current item matched, we want to check the next item
if (scanFor.Length <= tempScanForIndex) //And if we checked enough items,
//we know that the array matches, so we can return the found index
return tempFoundIndex;
}
else
{
arrayCheckFailed = true;
//If it didn't match we continue to search for a first item which matches
tempFoundIndex = -1;
break;
}
}
}
}
return tempFoundIndex;
}
我用这种方法测试了这个:
private static void Main ()
{
Console.Write (ArraySearch (ThirdPart.Select ((b, i) => i == 0 ? (byte) 0xFF : b).ToArray (), 0, 1100));
Console.ReadLine ();
}
输出为249
,这对我来说是正确的。
我无法在您的环境中对其进行测试,因此,如果某些内容无法正常工作,请通知我。