C语言 用特定长度的随机字节生成NSData对象的最佳方法是什么?

insrf1ej  于 2023-01-01  发布在  其他
关注(0)|答案(9)|浏览(162)

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

0vvn1miw

0vvn1miw1#

你可以创建一个202^20b的NSData对象,然后用arc4random()将一个随机的4字节整数附加到它上面202^20/4次,我相信你需要包含stdlib.h(通过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;
}
c2e8gylq

c2e8gylq2#

void * bytes = malloc(numberOfBytes);
NSData * data = [NSData dataWithBytes:bytes length:numberOfBytes];
free(bytes);

字节不是“随机”的,但是会包含垃圾值(在运行之前堆上的任何东西)。优点是它的速度快,代码简洁。

1wnzp6jl

1wnzp6jl3#

下面是一个3行的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))

雨燕3号

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

rpppsulh4#

您可以考虑使用CommonCrypto中的CCRandomGenerateBytes函数来生成随机数据。

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

7lrncoxx5#

雨燕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
}
    • Swift 5更新:**
func randomBytes(length: Int) -> Data? {
    var data = Data(count: length)
    let result = data.withUnsafeMutableBytes {
        SecRandomCopyBytes(kSecRandomDefault, length, $0.baseAddress!)
    }
    guard result == errSecSuccess else {
        return nil
    }
    return data
}

感谢this帖子。

nwo49xxi

nwo49xxi6#

使用arc4random_buf用随机字节填充缓冲区

目标-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];
}
xnifntxz

xnifntxz7#

原来的版本有一个错误,但我的照顾,希望不会引入任何新的一个。希望它的帮助。

- (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;
}

下面是它的单元测试:

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

7gyucuyw8#

铀的效率更高。
下面是生成随机缓冲区的类别:

@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
r1zk6ea1

r1zk6ea19#

我已经在github开源了我的JFRandom类,它可以做到这一点。这里有一篇博客文章演示了如何获得/使用它来实现你的目标...
http://jayfuerstenberg.com/devblog/generating-random-numbers-strings-and-data-in-objective-c

相关问题