If I create a new NSData object of a specific size using dataWithBytes:length:, what is the most efficient way to create the input bytes (20 Mb worth) of random characters, preferably without reading the data in from a file? I need a unique buffer of a specific size each time.
Thanks
You can create a 20*2^20b NSData
object, then append a random 4 byte integer to it 20*2^20/4 times with arc4random()
. I believe you need to include stdlib.h
(via Generating random numbers in Objective-C).
#include <stdlib.h>
-(NSData*)create20mbRandomNSData
{
int twentyMb = 20971520;
NSMutableData* theData = [NSMutableData dataWithCapacity:twentyMb];
for( unsigned int i = 0 ; i < twentyMb/4 ; ++i )
{
u_int32_t randomBits = arc4random();
[theData appendBytes:(void*)&randomBits length:4];
}
return theData;
}
void * bytes = malloc(numberOfBytes);
NSData * data = [NSData dataWithBytes:bytes length:numberOfBytes];
free(bytes);
The bytes are not 'random', but will contain garbage values (whatever was on the heap before this was run). The advantage being its fast and the code is concise.
Here's a 3-liner swift version:
let length = 2048
let bytes = [UInt32](count: length, repeatedValue: 0).map { _ in arc4random() }
let data = NSData(bytes: bytes, length: bytes.count * sizeof(UInt32))
let bytes = [UInt32](repeating: 0, count: length).map { _ in arc4random() }
let data = Data(bytes: bytes, count: length)
You might consider using CCRandomGenerateBytes
function from CommonCrypto
to generate random data. Like:
func generateBytes(length : Int) throws -> NSData? {
var bytes = [UInt8](count: length, repeatedValue: UInt8(0))
let statusCode = CCRandomGenerateBytes(&bytes, bytes.count)
if statusCode != CCRNGStatus(kCCSuccess) {
return nil
}
return NSData(bytes: bytes, length: bytes.count)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With