Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to concatenate 3 NSData variables

How to concatenate 3 NSData variables ?

NSData *iv;
NSData *salt;
NSData *encryptedData;

I need to join these to a single variable. Can any one show me a way.

like image 932
Deepak Pillai Avatar asked Sep 14 '12 12:09

Deepak Pillai


2 Answers

use an NSMutableData object and the method -(void)appendData:(NSData *)otherData

Edited to add example :

NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:iv];
[concatenatedData appendData:salt];
[concatenatedData appendData:encryptedData];
// and now you have all of the data in the single variable "concatenatedData"
like image 117
Moxy Avatar answered Nov 17 '22 04:11

Moxy


For those who coding for iOS5 and later. I'd like to show some real good concatenation. Why are those answers aren't good enough? Because they are involves extra memory usage for copied data. Let's see the answer:

NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:iv];
[concatenatedData appendData:salt];
[concatenatedData appendData:encryptedData];

here we have memory allocated for iv, salt and encryptedData also each time we append one of them to our mutable concatenation we are obviously copy it to mutable data again. Do we want this extra expenses while dealing with large data? Me not.

There is a way to avoid this unnecessary expense of memory - dispatch_data I'm not going to explain how it works, you can google it if you want. I just give you a code that works:

NSData *iv = [@"some data" dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [@"even more data" dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [@"and one more" dataUsingEncoding:NSUTF8StringEncoding];
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_data_t dispatch_data_iv = dispatch_data_create([iv bytes], [iv length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
dispatch_data_t dispatch_data_salt = dispatch_data_create([salt bytes], [salt length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
dispatch_data_t dispatch_data_encrypted = dispatch_data_create([encryptedData bytes], [encryptedData length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
iv = nil; salt = nil; encryptedData = nil; // free all parts, we dont need it anymore
dispatch_data_t dispatch_data_concat = dispatch_data_create_concat( dispatch_data_create_concat(dispatch_data_iv, dispatch_data_salt), dispatch_data_encrypted);
NSData *concatenatedNSData = DataFromDispatchData(dispatch_data_concat);

// lets check now if the concatenation works properly
NSString *stringFromConcatenatedNSData = [[NSString alloc]initWithData:concatenatedNSData encoding:NSUTF8StringEncoding];
NSLog(@"%@",stringFromConcatenatedNSData); 

don't forget about the helper-converter

NSData *DataFromDispatchData(dispatch_data_t data)
{
    NSMutableData *result = [NSMutableData dataWithCapacity: dispatch_data_get_size(data)];
    dispatch_data_apply(data, ^(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
        [result appendBytes:buffer length:size];
        return (_Bool)true;
    });
    return result;
}
like image 23
kas-kad Avatar answered Nov 17 '22 05:11

kas-kad