从 NSData 中提取子数据而不复制

Posted

技术标签:

【中文标题】从 NSData 中提取子数据而不复制【英文标题】:Extract subdata from NSData without copying 【发布时间】:2014-01-24 13:18:24 【问题描述】:

我有以下情况:我需要解密一个 NSData。数据包括:

定长文件头 加密内容

我正在使用 CCCrypt 进行解密,但这可能并不重要,因为这更像是一个与 NSData 相关的问题。这就是我现在分离事物的方式(伪代码):

int hdrsize; // this contains the size of the header
NSData *data; // this contains full encrypted data with a header

// this gives me information, stored in the header + some additional stuff
NSDictionary *hdr = [self _headerInfoFromData:data];

// THIS IS THE PROBLEM AREA
data = [data subdataWithRange:NSMakeRange(hdrsize, [data length] - hdrsize)];

// And the decryption part
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, MS_SEC_ENC_ALGORITHM, kCCOptionPKCS7Padding,
                                      [key bytes], MS_SEC_ENC_KEY_SIZE,
                                      [[hdrdict objectForKey:@"iv"] bytes],
                                      [data bytes], dataLength,
                                      buffer, bufferSize,

如您所见,我的问题是,为了解密,我需要提取没有标头的 NSData 部分。但是有没有办法以某种方式简单地“重用”已经存在的字节而不是制作副本?也许有某种方法可以从中创建一个无复制字节缓冲区,跳过前 X 个字节并将其传递给 CCCrypt?

感谢您的帮助

【问题讨论】:

【参考方案1】:

您是否验证过-subdataWithRange: 确实复制了字节?如果是这样,您可以随时使用+dataWithBytesNoCopy:length:,只要确保正确处理所有权即可。

编辑

我真是个傻瓜。只需这样做:

int hdrsize; // this contains the size of the header
NSData *data; // this contains full encrypted data with a header

// this gives me information, stored in the header + some additional stuff
NSDictionary *hdr = [self _headerInfoFromData:data];

// And the decryption part
CCCryptorStatus cryptStatus = CCCrypt(
    kCCDecrypt,
    MS_SEC_ENC_ALGORITHM,
    kCCOptionPKCS7Padding,
    [key bytes],
    MS_SEC_ENC_KEY_SIZE,
    [[hdrdict objectForKey:@"iv"] bytes],
    data.bytes + hdrsize,
    data.length - hdrsize,
    buffer,
    bufferSize,

【讨论】:

应该是-dataWithBytesNoCopy:length:freeWhenDone: 我知道 dataWithBytesNoCopy,但我需要它跳过前 X 个字节。而且我认为这可以通过指针和其他东西来完成,但我对此很糟糕。 这很简单,只需使用 data.bytes 作为指针并添加要跳过的字节数,比如[NSData dataWithBytesNoCopy:data.byes + hdrSize length:data.length - hdrSize freeWhenDone:NO] 创建的对象将完全依赖于原始数据,如果数据被释放,派生对象将在访问其内容时使应用程序崩溃。 Stefan - 这正是我正在寻找的指针。谢谢!所有权和原始数据不会有问题;]

以上是关于从 NSData 中提取子数据而不复制的主要内容,如果未能解决你的问题,请参考以下文章

使用归档器复制 UIView - 内存释放?

如何从 textbox1 复制字符串,并在子进程命令中使用,并在 textbox2 中输出

将参数传递给 Perl 子例程时,是不是会影响数据复制性能?

如何有条件地将子字符串复制到熊猫数据框的新列中?

CouchDB 复制而不删除文档

如何以编程方式将 NSData 转换为 NSString? [复制]