RandomSequence是一个简单的库,用于在Mac和iOS上生成可重复的伪随机数序列。与像rand()和arc4random()这样的C随机函数不同,它可以轻松创建多个独立运行的RandomSequence实例,可以单独设置为已知的任何状态。
注意:“支持”表示库已与该版本进行了测试。“兼容”表示库应在该操作系统版本上运行(即它不依赖于任何不可用的SDK功能),但不再测试与兼容性,可能需要调整或错误修复才能正常运行。
RandomSequence与ARC和非ARC编译目标兼容。
任何一个RandomSequence实例应该只从单个线程中访问,然而,可以在不同线程上并发地使用多个RandomSequence实例。
要在一个应用程序中使用RandomSequence类,只需将RandomSequence类文件(不需要任何演示文件或资源)拖放到你的项目中。
RandomSequence类只有一个属性
@property (nonatomic, assign) uint32_t seed;
种子值代表序列的当前状态。它用于生成 value
方法返回的值,以及计算下一个种子。当您创建一个新的 RandomSequence 实例时,种子会自动设置为使用 arc4random() 生成的任意值,因此每个创建的实例的序列都是唯一的。要创建可重复的序列,请在使用之前将种子设置为已知值。为了保存和恢复给定序列到特定点的状态,只需记录当前的种子值并在稍后恢复即可。种子值必须在 0 和 233280 之间,但较大的值将被自动包裹到该范围内。
RandomSequence 类有如下方法
+ (instancetype)defaultSequence;
此方法返回使用首次调用时的当前时间初始化的共享默认序列。
+ (instancetype)sequenceWithSeed:(uint32_t)seed;
此方法返回一个具有指定种子值的新、自动释放的 RandomSequence 实例。
- (double)value;
此方法返回当前的序列值,它是在 0.0 - 1.0 范围内的双精度浮点数(请注意,值将始终略小于 1.0,因此 floor(value)
总是等于零,并且 floor(value * SOME_POSITIVE_INTEGER)
从不超出 SOME_POSITIVE_INTEGER - 1
,这对于创建随机数组索引是很有用的)。
- (double)nextValue;
此方法返回当前的伪随机序列值,就像 value
方法一样,但是除了返回值之外,它还使种子前进到序列中的下一个值。因此,连续调用 nextValue
将在每次调用时返回一个新的伪随机值。
- (NSUInteger)nextIntegerInRange:(NSRange)range;
此方法返回指定范围内的随机正整数。类似于 nextValue
,此方法将种子前进到序列中的下一个值,因此连续调用此方法将每次返回新的值。
- (NSInteger)nextIntegerFrom:(NSInteger)from to:(NSInteger)to;
此方法返回指定范围内的随机整数。与 nextIntegerInRange:
不同,from 和 to 可以是负数,并且 to 可以小于 from。与 nextValue
类似,此方法将种子前进到序列中的下一个值,因此连续调用此方法将每次返回新的值。
RandomSequence 通过以下分类方法扩展了 NSArray
- (NSUInteger)randomIndexWithSequence:(RandomSequence *)sequence;
此方法使用指定的序列对象返回数组内的随机索引。类似于 RandomSequence 的 nextValue
,此方法将种子前进到序列中的下一个值,因此使用同一序列实例重复调用此方法将返回不同的索引。
- (id)randomObjectWithSequence:(RandomSequence *)sequence;
此方法使用指定的序列对象返回数组内的随机对象。类似于 RandomSequence 的 nextValue
,此方法将种子前进到序列中的下一个值,因此使用同一序列实例重复调用此方法将返回不同的对象。
- (NSArray *)shuffledArrayWithSequence:(RandomSequence *)sequence;
此方法使用指定的序列对象对数组进行洗牌。内部会反复调用 RandomSequence 的 nextValue
方法,因此序列的种子将被修改,并且在同一序列实例上重复调用此方法将返回不同的数组顺序。
RandomSequence 通过以下分类方法扩展了 NSMutableArray
- (void)shuffleWithSequence:(RandomSequence *)sequence;
此方法使用指定的序列对象对数组进行洗牌。内部会反复调用 RandomSequence 的 nextValue
方法,因此序列的种子将被修改。
RandomSequence 符合 NSCopying 和 NSCoding 协议。这允许你在特定位置制作一个序列的副本(例如,如果你想后来能够重复使用相同的序列)并且/或者将其保存到磁盘,以便序列可以在以后从相同的位置恢复。
生成随机数的算法相当简单。每个新的种子都使用下面的函数从上一个值生成:
_seed = (_seed * 9301 + 49297) % 233280;
这提供了一个相当随机的序列,可以使用支持 32 位整数运算的任何编程语言轻松地重建,这对于想在服务器端复制序列逻辑非常有用。