加速随机数生成

出于多种原因,您迟早会开始创建或使用随机数据:

  • 创建ssh和PGP密钥创建证书做财务模拟为您的测试提供大量数据渗透测试和道德黑客攻击期间的暴力攻击在游戏引擎中添加变化

还有很多很多 随机性的反义词是确定性,这引发了一个哲学问题:在我们不断努力争取确定性的同时,我们的许多成功都取决于随机性是否有趣? 我认为在谈论随机性和随机数据时,我们确实需要有限随机性:在特定界限内且具有一定品质。 例如,如果要模拟掷骰子,显然需要一个随机数据源,它发出两个不同的值。 您还需要在所有试验中这些值的分布具有随机性。 这意味着您不希望能够识别模式(充其量,随机数据与噪声是不可区分的,就像加密数据一样)。

在测试中,您需要很多数据的!

因此,您基本上有两个选择:

  • 密码安全的随机数生成密码学上不安全的随机数生成

大多数时候,您可能希望测试通用功能,而无需使用加密安全的随机数据。 如果您需要创建数千个模拟用户的个人数据的数据集,那么不管街道上的名称或字符是否重复都没关系。 测试加密软件只能由该领域的专家来完成(因为您绝不能自己成为加密专家而不是专家)。

大多数编程语言为两种类型的随机数提供适当的功能和方法。

那么,何必呢?

问题在于每个时间单位可以产生的性能或随机数的数量。 确切地说,是在加密安全的随机数生成方面。 它的性能依赖于所谓的熵池,其中所有可用的随机事件源都提供附加数据以在该熵池中生成数据。 仅当池足够大时才生成新数字。 Linux内核通常具有三个用于获取新随机数据的源:输入层,中断数据和磁盘。 您可能会认为像样的Linux服务器应该从这些来源获得大量事件,但它只会向池中添加非常具体的数据。 从random.c引用(1):

 * add_disk_randomness() uses what amounts to the seek time of block
 * layer request events, on a per-disk_devt basis, as input to the
 * entropy pool. Note that high-speed solid-state drives with very low
 * seek times do not make for good sources of entropy, as their seek
 * times are usually fairly consistent.

如今,高速SSD并不少见。 因此,高IO不能保证快速随机。 引用(2)从random.c:

 * add_interrupt_randomness() uses the interrupt timing as random
 * inputs to the entropy pool. Using the cycle counters and the irq source
 * as inputs, it feeds the randomness roughly once a second.

一秒钟(!),那不是很快。 引用(3)从random.c:

 * add_input_randomness() uses the input layer interrupt timing, as well as
 * the event type information from the hardware.

是的:输入速度更快,伙计! 我们需要更多的熵!

您可能会问:没有更多的事件来源吗? 当然可以,但问题始终是相同的:它真的是高质量随机性的来源吗?

所以几天前,我碰到了这种情况: 基于Java的测试在第一次运行时运行速度很快,每次连续运行都会延迟2-3分钟。 这是一台具有大量CPU的中型服务器,只要SSD和Jenkins服务器,没人在控制台上打字(典型的是无头)。

测试数据是使用Java的默认随机类生成的,该类默认情况下使用的是/ dev / random中的数据,而Linux内核的熵池提供了该数据。 第一次测试后,池变空了,接下来的池延迟了几分钟。 这是可重复的:触发Jenkins建立工作,并观察第一个测试后卡住的测试。 / dev / random与/ dev / urandom的性能差异:

# urandom
dd if=/dev/urandom of=/dev/null bs=1 count=10M
10485760+0 records in
10485760+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 10.6776 s, 982 kB/s

# random
dd if=/dev/random of=/dev/null bs=1 count=10M
10485760+0 records in
10485760+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 852.927 s, 12.3 kB/s

12.3 kB / s-令人痛心...但是可以解释(见上文)。

因此,基本上有两种选择:

  • 强制Java使用不依赖/ dev / random的伪数字生成器使伪数字生成更快

要使Java使用/ dev / random之外的其他东西很容易:您需要调整文件jre / lib / security / java.security并设置securerandom.source。 默认情况下,它设置为securerandom.source = file:/ dev / random,这是熵池的提要,并且在没有更多随机值可用时可能会阻塞。 要使用非阻塞随机源,请将其设置为securerandom.source = file:/ dev / urandom。

Linux随机状态手册页:

The /dev/random interface is considered a legacy interface, and 
/dev/urandom is preferred and sufficient in all use cases, with 
the exception of applications which require randomness during 
early boot time; for these  applications, getrandom(2) must be 
used instead, because it will block until the entropy pool is initialized.

在我们的案例中,使用者是由Jenkins启动的Java进程,因此在早期启动期间不需要随机性。

如果您好奇并想知道熵池中当前有多少随机数据,请发出以下命令:

cat /proc/sys/kernel/random/entropy_avail

每个低于1.000的数字都可以认为太低,无法正常运行; 如果您请求的数据多于可用数据,则请求过程将被阻止。

To speed up the generation of random data means to add a performant event source for the entropy pool. Such a source needs to generate data with a certain quality and independent from things like user input or disk movements: it must be reliably available even under cloud conditions, e.g. headless operations which are some of a norm today.
One way to do that is to use more data which is rather random and available in higher amounts: statistics of CPU instruction execution. There is an algorithm which was designed to leverage from this, HArdware Volatile Entropy Gathering and Expansion (HAVEGE, details are here). As the execution time for instructions are not predictable due to a large number of optimizations and environment conditions (process switching, cache hits and misses, memory access etc.), this source is able to generate high-quality random data at high rates. The original paper talks about several hundred megabits per second.

Luckily there is an Open Source implementation available haveged.
Your package system should be able to provide a version if:

apt install haveged

应该在Debian或Ubuntu系统上进行工作。 一旦运行,您应该能够看到随机数生成性能的提高,如下所示:

dd if=/dev/random of=/dev/null bs=1 count=10M
10485760+0 records in
10485760+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 32.7755 s, 320 kB/s

在这里,我们可以看到性能大约提高了25倍。 我对系统中熵的用法感到很好奇,并发布了该消息以进行观察:

while true ; do echo $(date) : $(cat /proc/sys/kernel/random/entropy_avail) ; sleep 1 ; done
Tue Mar 12 13:44:20 CET 2019 : 2900
Tue Mar 12 13:44:21 CET 2019 : 2907
Tue Mar 12 13:44:22 CET 2019 : 2915
Tue Mar 12 13:44:23 CET 2019 : 2920
Tue Mar 12 13:44:24 CET 2019 : 2927
Tue Mar 12 13:44:25 CET 2019 : 2932
Tue Mar 12 13:44:26 CET 2019 : 2939
Tue Mar 12 13:44:27 CET 2019 : 2951
Tue Mar 12 13:44:28 CET 2019 : 2952
Tue Mar 12 13:44:29 CET 2019 : 2956
Tue Mar 12 13:44:30 CET 2019 : 2958
Tue Mar 12 13:44:31 CET 2019 : 2963
Tue Mar 12 13:44:32 CET 2019 : 2967
Tue Mar 12 13:44:33 CET 2019 : 2974
Tue Mar 12 13:44:34 CET 2019 : 2981
Tue Mar 12 13:44:35 CET 2019 : 2991
Tue Mar 12 13:44:36 CET 2019 : 2994
Tue Mar 12 13:44:37 CET 2019 : 3003
Tue Mar 12 13:44:38 CET 2019 : 3005
Tue Mar 12 13:44:39 CET 2019 : 3012
Tue Mar 12 13:44:40 CET 2019 : 3014
Tue Mar 12 13:44:41 CET 2019 : 3019
Tue Mar 12 13:44:42 CET 2019 : 3023
Tue Mar 12 13:44:43 CET 2019 : 3026
Tue Mar 12 13:44:44 CET 2019 : 3027
Tue Mar 12 13:44:45 CET 2019 : 3035
Tue Mar 12 13:44:46 CET 2019 : 3036
Tue Mar 12 13:44:47 CET 2019 : 3045
Tue Mar 12 13:44:48 CET 2019 : 3050
Tue Mar 12 13:44:49 CET 2019 : 3052
Tue Mar 12 13:44:50 CET 2019 : 3055
Tue Mar 12 13:44:51 CET 2019 : 3058
Tue Mar 12 13:44:52 CET 2019 : 3061
Tue Mar 12 13:44:53 CET 2019 : 3064
Tue Mar 12 13:44:54 CET 2019 : 3066
Tue Mar 12 13:44:55 CET 2019 : 3074
Tue Mar 12 13:44:56 CET 2019 : 3078
Tue Mar 12 13:44:57 CET 2019 : 3084
Tue Mar 12 13:44:58 CET 2019 : 3087
Tue Mar 12 13:44:59 CET 2019 : 3090
Tue Mar 12 13:45:00 CET 2019 : 3095
Tue Mar 12 13:45:01 CET 2019 : 3102
Tue Mar 12 13:45:02 CET 2019 : 3108
Tue Mar 12 13:45:03 CET 2019 : 3112
Tue Mar 12 13:45:04 CET 2019 : 3114
Tue Mar 12 13:45:05 CET 2019 : 3119
Tue Mar 12 13:45:06 CET 2019 : 3122
Tue Mar 12 13:45:07 CET 2019 : 3129
Tue Mar 12 13:45:08 CET 2019 : 3130
Tue Mar 12 13:45:09 CET 2019 : 3135
Tue Mar 12 13:45:10 CET 2019 : 3136
Tue Mar 12 13:45:11 CET 2019 : 3139
Tue Mar 12 13:45:12 CET 2019 : 3142
Tue Mar 12 13:45:13 CET 2019 : 3144

您可以在此处看到系统中对随机数据的持续需求。

如果您需要更多随机数据,则可能需要专用硬件。

快乐黑客:-)

from: https://dev.to//pythonmeister/speedup-random-number-generation-4f81

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值