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, pref
Use arc4random_buf
to fill the buffer with random bytes
Obj-C
+ (nullable NSData *)radomDataOfSize:(size_t)sizeInBytes
{
void *buff = malloc(sizeInBytes);
if (buff == NULL) {
return nil;
}
arc4random_buf(buff, sizeInBytes);
return [NSData dataWithBytesNoCopy:buff length:sizeInBytes freeWhenDone:YES];
}
Swift 3:
import Security
func randomBytes(length: Int) -> Data {
var data = Data(capacity: length)
data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in
let _ = SecRandomCopyBytes(kSecRandomDefault, length, bytes)
}
return data
}
I've open sourced my JFRandom class over at github which can do exactly this. Here's a blog post demonstrating how to obtain/use it to achieve your goal...
http://jayfuerstenberg.com/devblog/generating-random-numbers-strings-and-data-in-objective-c
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)
}
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)
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.