Le meilleur moyen de générer un object NSData avec des octets aléatoires d’une longueur spécifique?

Si je crée un nouvel object NSData d’une taille spécifique en utilisant dataWithBytes: length: quelle est le moyen le plus efficace de créer les octets d’entrée (d’une valeur de 20 Mo) de caractères aléatoires, de préférence sans lire les données d’un fichier? J’ai besoin d’un tampon unique d’une taille spécifique à chaque fois.

Merci

Vous pouvez créer un object NSData 20 * 2 ^ 20b, puis lui append un entier aléatoire de 4 octets 20 * 2 ^ arc4random() avec arc4random() . Je crois que vous devez inclure stdlib.h (via Générer des nombres aléatoires dans Objective-C ).

 #include  -(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); 

Les octets ne sont pas “aléatoires”, mais contiendront des valeurs parasites (tout ce qui était sur le tas avant que cela soit exécuté) L’avantage est sa rapidité et le code est concis.

Voici une version rapide à 3 lignes:

Swift 2

 let length = 2048 let bytes = [UInt32](count: length, repeatedValue: 0).map { _ in arc4random() } let data = NSData(bytes: bytes, length: bytes.count * sizeof(UInt32)) 

Swift 3

 let bytes = [UInt32](repeating: 0, count: length).map { _ in arc4random() } let data = Data(bytes: bytes, count: length) 

Vous pouvez envisager d’utiliser la fonction CommonCrypto de CommonCrypto pour générer des données aléatoires. Comme:

 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) } 

La version originale a un bug mais la mienne s’en occupe et, espérons-le, n’en introduit pas de nouvelle. J’espère que ça aide.

 - (NSData *)randomDataWithBytes: (NSUInteger)length { NSMutableData *mutableData = [NSMutableData dataWithCapacity: length]; for (unsigned int i = 0; i < size; i++) { NSInteger randomBits = arc4random(); [mutableData appendBytes: (void *) &randomBits length: 1]; } return mutableData; } 

Voici son test unitaire:

 NSInteger givenLength = INT16_MAX; NSData *randomData = [self randomDataWithBytes: givenLength]; STAssertTrue([randomData length] == givenLength, @"RandomDataWithBytes Failed Expected size %d and got %d", givenLength, [randomData length]); 

Swift 3:

 import Security func randomBytes(length: Int) -> Data { var data = Data(capacity: length) data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in let _ = SecRandomCopyBytes(kSecRandomDefault, length, bytes) } return data } 

urandom est plus efficace.

Voici une catégorie pour générer des tampons aléatoires:

 @interface NSMutableData(Random) +(id)randomDataWithLength:(NSUInteger)length; @end @implementation NSMutableData(Random) +(id)randomDataWithLength:(NSUInteger)length { NSMutableData* data=[NSMutableData dataWithLength:length]; [[NSInputStream inputStreamWithFileAtPath:@"/dev/urandom"] read:(uint8_t*)[data mutableBytes] maxLength:length]; return data; } @end 

J’ai open source ma classe JFRandom sur github qui peut faire exactement cela. Voici un article de blog montrant comment l’obtenir / l’utiliser pour atteindre votre objective …

http://jayfuerstenberg.com/devblog/generating-random-numbers-ssortingngs-and-data-in-objective-c