NSData查找字节序列

3

我需要在我的图像数据中找到字节序列。我有下面的Java代码,但我需要用Objective-C实现同样的功能。

private static int searchInBuffer(byte[] pBuf, int iBufferLen) {
    for(int i = 0; i<iBufferLen - 7; i++) {
        if (pBuf[i] == 'l' && pBuf[i + 1] == 'i' && pBuf[i + 2] == 'n' && pBuf[i + 3] == 'k')
        return (int)pBuf[i + 4];
    }
    return -1;
}

public static int checkFlagInJpeg(String pFullFileName) {
    int iRes = -1;
    try {
        File f = new File(pFullFileName);
        FileInputStream is = new FileInputStream(f);
        int iBufferSize = 6 * 1024, iCount = 15;
        byte buf[] = new byte[iBufferSize];

        while((is.available() > 0) && (iCount >= 0)) {
            int iRead = is.read(buf),
            iFlag = searchInBuffer(buf, iRead);
            if (iFlag > 0) {
                iRes = iFlag;
                break;
            }
            iCount--;
        }
        is.close();
    }
}

Obj-C(我的版本):

    UIImage *image = [UIImage imageWithCGImage:[[[self.assets objectAtIndex:indexPath.row] defaultRepresentation] fullScreenImage]];
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);

    NSUInteger length = MIN(6*1024, [imageData length]);
    Byte *buffer = (Byte *)malloc(length);
    memcpy(buffer, [imageData bytes], length);

    for (int i=0; i < length - 1; i++) {
        if (buffer[i] == 'l' && buffer[i + 1] == 'i' && buffer[i + 2] == 'n' && buffer[i + 3] == 'k')
            NSLog(@"%c", buffer[i + 4]);
    }
    free(buffer);

我仍然不确定我是否完全理解了字节处理的所有方面,所以我需要帮助。

更新: 问题在于获取图像数据。在Martin R.的帮助下,我将两个解决方案合并为一个,并得到了下一个工作代码:

ALAssetRepresentation *repr = [[self.assets objectAtIndex:indexPath.row] defaultRepresentation];
        NSUInteger size = (NSUInteger) repr.size;
        NSMutableData *data = [NSMutableData dataWithLength:size];

        NSError *error;
        [repr getBytes:data.mutableBytes fromOffset:0 length:size error:&error];

        NSData *pattern = [@"link" dataUsingEncoding:NSUTF8StringEncoding];
        NSRange range = [data rangeOfData:pattern options:0 range:NSMakeRange(0, data.length)];

        int iRes = -1;
        if (range.location != NSNotFound) {
            uint8_t flag;
            [data getBytes:&flag range:NSMakeRange(range.location + range.length, 1)];
            iRes = flag;
        }

        NSLog(@"%i", iRes);

它完美地运行了!再次感谢你!


几点建议。首先,循环应该遍历 i < length - 4 ,以避免检查范围外的字节。其次,只检查第一个字节。如果不匹配就继续下一个。不要每次都检查所有四个字节。 - Putz1103
不需要使用memcopy,只需使用imagedata.bytes,它是指向NSData的字节指针。 - zaph
此外,您不需要复制数据即可完成此操作。 - trojanfoe
1
@Putz1103 发布的代码只检查了一个字节。在基于C的语言中(包括Java和Objective-C),if语句使用“短路”评估。由于该表达式只有在所有四个部分都为真时才可能为真,因此它会在其中一个部分为假时立即返回false,从而防止其他部分被评估。因此,如果buffer[i] != 'l',则其他三个部分根本不会被评估。 - rmaddy
1个回答

8

NSData有一个方法rangeOfData:...,你可以使用它来查找模式:

NSData *pattern = [@"link" dataUsingEncoding:NSUTF8StringEncoding];
NSRange range = [imageData rangeOfData:pattern options:0 range:NSMakeRange(0, imageData.length)];

如果找到了该模式,获取下一个字节:

int iRes = -1;
if (range.location != NSNotFound && range.location + range.length < imageData.length) {
    uint8_t flag;
    [imageData getBytes:&flag range:NSMakeRange(range.location + range.length, 1)];
    iRes = flag;
}

谢谢,但它不起作用。iRes始终为-1。但是,如果我在文本编辑器中打开我的图像,我可以找到带有“链接”的行。所以也许我需要以UTF8的方式读取imageData? - Vladislav Kovalyov
1
@VladislavKovalyov:不是的。- 但问题可能在于,通过所有转换asset->defaultRepresentation->fullscreenImage->UIImageJPEGRepresentation,您不一定会获得原始图像数据。 - Martin R
1
@VladislavKovalyov:这可能会有所帮助:http://stackoverflow.com/a/12121605/1187415。- 你能解释一下为什么要在JPEG数据中查找“link”文本吗? - Martin R
@VladislavKovalyov:你是怎样获得“带有图像EXIF的字典”的? - Martin R
我从元数据中获取了它。但这已经不重要了,因为有了你的帮助,我解决了这个问题!谢谢! - Vladislav Kovalyov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接