美文网首页iOS开发_其他
Swift中的随机数获取

Swift中的随机数获取

作者: kobehjk | 来源:发表于2017-08-08 15:12 被阅读288次

整型随机数
如果我们想要一个整型的随机数,则可以考虑用arc4random系列函数。我们可以通过man arc4random命令来看一下这个函数的定义:
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be inabout (21700) states. The arc4random() function returns pseudo-random numbers in the range of 0 to (232)-1, and therefore has twice the range of rand(3) and random(3).
arc4random使用了arc4密码加密的key stream生成器(请脑补),产生一个[0, 2^32)区间的随机数(注意是左闭右开区间)。这个函数的返回类型是UInt32。如下所示:

arc4random()                
// 2,919,646,954

如果我们想生成一个指定范围内的整型随机数,则可以使用arc4random() % upper_bound的方式,其中upper_bound指定的是上边界,如下处理:

arc4random() % 10            

不过使用这种方法,在upper_bound不是2的幂次方时,会产生一个所谓Modulo bias(模偏差)的问题。
我们在控制台中通过man arc4random命令,可以查看arc4random的文档,有这么一条:
arc4random_uniform() will return a uniformly distributed random number less than upper_bound. arc4random_uniform() is recommended over constructions like ‘’arc4random() % upper_bound’‘ as it avoids “modulo bias” when the upper bound is not a power of two.
因此可以使用arc4random_uniform,它接受一个UInt32类型的参数,指定随机数区间的上边界upper_bound,该函数生成的随机数范围是[0, upper_bound),如下所示:

arc4random_uniform(10)       

而如果想指定区间的最小值(如随机数区间在[5, 100)),则可以如下处理:

let max: UInt32 = 100

let min: UInt32 = 5

arc4random_uniform(max - min) + min           

当然,在Swift中也可以使用传统的C函数rand与random。不过这两个函数有如下几个缺点:
这两个函数都需要初始种子,通常是以当前时间来确定。
这两个函数的上限在RAND_MAX=0X7fffffff(2147483647),是arc4random的一半。
rand函数以有规律的低位循环方式实现,更容易预测
我们以rand为例,看看其使用:

srand(UInt32(time(nil)))            
// 种子,random对应的是srandom

rand()                              
// 1,314,695,483

rand() % 10                          

64位整型随机数
在大部分应用中,上面讲到的几个函数已经足够满足我们获取整型随机数的需求了。不过我们看看它们的函数声明,可以发现这些函数主要是针对32位整型来操作的。如果我们需要生成一个64位的整型随机数呢?毕竟现在的新机器都是支持64位的了。
目前貌似没有现成的函数来生成64位的随机数,不过jstn在stackoverflow上为我们分享了他的方法。我们一起来看看。
他首先定义了一个泛型函数,如下所示:

func arc4random  (type: T.Type) -> T {  
  var r: T = 0
  arc4random_buf(&r, UInt(sizeof(T)))   
  return r
}

这个函数中使用了arc4random_buf来生成随机数。让我们通过man arc4random_buf来看看这个函数的定义:
arc4random_buf() function fills the region buf of length nbytes with ARC4-derived random data.
这个函数使用ARC4加密的随机数来填充该函数第二个参数指定的长度的缓存区域。因此,如果我们传入的是sizeof(UInt64),该函数便会生成一个随机数来填充8个字节的区域,并返回给r。那么64位的随机数生成方法便可以如下实现:

extension UInt64 {
static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {   
  var m: UInt64
 
  let u = upper - lower
       
  var r = arc4random(UInt64)
       
  if u > UInt64(Int64.max) {

    m = 1 + ~u
   
  } else{
          
    m = ((max - (u * 2)) + 1) % u
        
  }        
  while r < m {
       
    r = arc4random(UInt64)
       
  }
      
  return (r % u) + lower
  
  }
}

我们来试用一下:

UInt64.random()                   
// 4758246381445086013

当然jstn还提供了Int64,UInt32,Int32的实现,大家可以脑补一下。
浮点型随机数
如果需要一个浮点值的随机数,则可以使用drand48函数,这个函数产生一个[0.0, 1.0]区间中的浮点数。这个函数的返回值是Double类型。其使用如下所示:

srand48(Int(time(nil)))

drand48()                       
// 0.396464773760275

记住这个函数是需要先调用srand48生成一个种子的初始值。

相关文章

  • Swift中的随机数获取

    整型随机数如果我们想要一个整型的随机数,则可以考虑用arc4random系列函数。我们可以通过man arc4ra...

  • 获取随机数

    获取随机数的几个小栗子 1.颜色随机 2.获取两数之间的随机数 指定值中获取随机数 4.获取随机的ip地址(0-255)

  • swift 随机数

    获取 Int 类型的随机数 调用方法如下: 获取Float 类型的随机数 调用方法如下: 获取CGFloat 类型...

  • [MySQL]随机数

    获取[0, 1)的随机数 select rand() 获取[i, j)的随机数 select floor(i + ...

  • Swift中关于NSClassFromString获取不到类

    Swift中关于NSClassFromString获取不到类 当Swift中调用OC写的类 直接 当Swift中调...

  • Swift中的随机数

    文章链接:https://www.sunyazhou.com/2018/06/Random/[https://ww...

  • Swift学习笔记 - OC中关于NSClassFromStri

    Swift学习笔记 - OC中关于NSClassFromString获取不到Swift类的解决方案 Swift学习...

  • 常用负载均衡算法

    1.随机 获取服务列表大小范围内的随机数,将随机数作为列表索引, 从服务列表中获取服务提供者。 2.加权随机 按照...

  • c课堂笔记 day-5

    冒泡排序 2.获取随机数 //获取0~100之间的随机数 srand(time(NULL));//此语句不能放在循...

  • 14 随机数生成器

    14.1 介绍 很多密码学系统需要使用到随机数。目前为止,本书只是假设可以获取到随机数。本章将介绍密码学中的随机数...

网友评论

    本文标题:Swift中的随机数获取

    本文链接:https://www.haomeiwen.com/subject/prbtrxtx.html