使用特定长度的随机字节生成NSData对象的最佳方法?

Bam*_*a91 16 c iphone objective-c nsdata

如果我使用dataWithBytes:length:创建一个特定大小的新NSData对象,那么创建输入字节(20 Mb值)随机字符的最有效方法是什么,最好不要从文件中读取数据?我每次都需要一个特定大小的独特缓冲区.

谢谢

Tho*_*mer 21

你可以创建一个20*2 ^ 20b的NSData对象,然后在它上面添加一个随机的4字节整数20*2 ^ 20/4次arc4random().我相信你需要包括stdlib.h(通过在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;
}
Run Code Online (Sandbox Code Playgroud)

  • 以为我会评论这段代码有漏洞.而不是分配NSMutabledata只需使用[NSMutableData dataWithCapacity:20MB]. (2认同)

Rob*_*ert 20

void * bytes = malloc(numberOfBytes);
NSData * data = [NSData dataWithBytes:bytes length:numberOfBytes];
free(bytes);
Run Code Online (Sandbox Code Playgroud)

这些字节不是"随机",而是包含垃圾值(在运行之前堆上的任何内容).其优点是速度快,代码简洁.

  • 值得注意的是,您应该对使用此数据的位置稍加注意.例如,随后将此数据发送到服务器并不是一个好主意 - 因为它基本上会提供内存转储. (3认同)
  • 这并不总是像你要求太多字节一样工作,malloc()将直接进入内核并分配页面,默认情况下这些页面是零.此外,如果您在应用程序启动后很快运行此代码段,则malloc具有之前从未使用过的返回内存(即来自新分配的页面),因此也将其清零. (2认同)

ldi*_*ual 13

这是一个3线程的快速版本:

斯威夫特2

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

斯威夫特3

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

  • 在Swift 3中,它是`let bytes = [UInt32](重复:0,count:length).map {_ in arc4random()} let data = Data(bytes:bytes,count:length)`.也许你想更新你的评论 (3认同)

sgl*_*l0v 6

您可以考虑使用CCRandomGenerateBytes函数from CommonCrypto来生成随机数据.喜欢:

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)
}
Run Code Online (Sandbox Code Playgroud)


gar*_*jon 5

斯威夫特 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
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特 5 更新:

func randomBytes(length: Int) -> Data? {
    var data = Data(count: length)
    let result = data.withUnsafeMutableBytes {
        SecRandomCopyBytes(kSecRandomDefault, 10, $0.baseAddress!)
    }
    guard result == errSecSuccess else {
        return nil
    }
    return data
}
Run Code Online (Sandbox Code Playgroud)

感谢这篇文章。