在二进制数据中查找string

我有一个二进制文件,我已经加载使用NSData对象。 有没有办法在二进制数据中find一个字符序列“abcd”,并返回偏移量而不将整个文件转换为string? 似乎应该是一个简单的答案,但我不知道该怎么做。 有任何想法吗?

我在iOS 3上这样做,所以我没有-rangeOfData:options:range: available。

我要把这一个奖给十六岁奥托build议strstr。 我去了,并find了C函数strstr的源代码,并重写它的工作在一个固定长度的字节数组 – 顺便不同于一个字符数组,因为它不是空终止。 这是我最终的代码:

 - (Byte*)offsetOfBytes:(Byte*)bytes inBuffer:(const Byte*)buffer ofLength:(int)len; { Byte *cp = bytes; Byte *s1, *s2; if ( !*buffer ) return bytes; int i = 0; for (i=0; i < len; ++i) { s1 = cp; s2 = (Byte*)buffer; while ( *s1 && *s2 && !(*s1-*s2) ) s1++, s2++; if (!*s2) return cp; cp++; } return NULL; } 

这返回一个指向第一个字节的指针,我正在寻找的东西,在缓冲区中,应该包含字节的字节数组。

我这样称呼它:

 // data is the NSData object const Byte *bytes = [data bytes]; Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]]; 

将您的子string转换为NSData对象,并使用rangeOfData:options:range:在较大的NSDatasearch这些字节。 确保string编码匹配!

在iPhone上,如果没有的话,你可能要自己做。 C函数strstr()会给你一个指向缓冲区中第一次出现的模式的指针(只要不包含空值!),而不是索引。 这是一个应该做这个工作的function(但没有承诺,因为我没有尝试真正的运行它):

 - (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack { const void* needleBytes = [needle bytes]; const void* haystackBytes = [haystack bytes]; // walk the length of the buffer, looking for a byte that matches the start // of the pattern; we can skip (|needle|-1) bytes at the end, since we can't // have a match that's shorter than needle itself for (NSUInteger i=0; i < [haystack length]-[needle length]+1; i++) { // walk needle's bytes while they still match the bytes of haystack // starting at i; if we walk off the end of needle, we found a match NSUInteger j=0; while (j < [needle length] && needleBytes[j] == haystackBytes[i+j]) { j++; } if (j == [needle length]) { return i; } } return NSNotFound; } 

这运行在类似O(nm)的地方,其中n是缓冲区长度,m是子string的大小。 它被写入与NSData工作有两个原因:1)这是你似乎手中,2)这些对象已经封装了实际字节和缓冲区的长度。

如果您使用的是Snow Leopard,则一种便捷的方法是NSData中的new -rangeOfData:options:range:方法,该方法返回第一个数据片段的范围。 否则,您可以使用-bytes方法自己访问NSData的内容来执行自己的search。

我有同样的问题。 相比之下,我解决了这个问题。

首先,我重新格式化数据(假设您的NSData存储在var rawFile中):

 NSString *ascii = [[NSString alloc] initWithData:rawFile encoding:NSAsciiStringEncoding]; 

现在,您可以使用NSScanner类轻松地进行stringsearch,如“abcd”或任何您想要的,并将asciistring传递给扫描器。 也许这不是真的有效,但它的工作,直到-rangeOfData方法将可用于iPhone也。