是否有可能向神经网络提供随机数生成器的输出,并期望它学习哈希(或生成器)函数,以便可以预测下一个生成的伪随机数是什么?
这样的东西已经存在了吗?如果已经对此或相关内容(与伪随机数的预测)进行了研究,那么谁能为我指出正确的资源?
目前,我正在查看该库及其相关链接。 https://github.com/Vict0rSch/deep_learning/tree/master/keras/recurrent
是否有可能向神经网络提供随机数生成器的输出,并期望它学习哈希(或生成器)函数,以便可以预测下一个生成的伪随机数是什么?
这样的东西已经存在了吗?如果已经对此或相关内容(与伪随机数的预测)进行了研究,那么谁能为我指出正确的资源?
目前,我正在查看该库及其相关链接。 https://github.com/Vict0rSch/deep_learning/tree/master/keras/recurrent
Answers:
如果我们谈论的是完美的RNG,答案肯定不是。不可能预测真正的随机数,否则就不是真正的随机数。
当我们谈论伪RNG时,情况有所改变。根据PRNG的质量,问题的范围从容易到几乎不可能。一个非常弱的PRNG像发布的XKCD一样,当然可以通过很少的训练就可以通过神经网络轻松预测。但是在现实世界中,情况看起来有所不同。
可以训练神经网络在PRNG生成的随机数历史中找到某些模式,以预测下一位。PRNG越强,假设您对PRNG产生的每一位先验随机性使用一个神经元,则需要更多的输入神经元。PRNG的可预测性越差,找到某种模式所需的数据就越多。对于强大的PRNG,这是不可行的。
从积极的方面来说,假设您可以控制PRNG并且可以生成任意数量的随机数,则可以为神经网络生成任意数量的训练模式,这对您很有帮助。
由于现代PRNG是密码学的关键组成部分,因此进行了广泛的研究,以验证它们是否“足够随机”以承受此类预测攻击。因此,我非常确定,利用当前可用的计算资源无法构建神经网络来成功攻击被认为对密码学安全的PRNG。
还值得注意的是,不必精确地预测PRNG的输出就可以破坏密码学-可以以50%的确定性来预测下一个比特,足以显着削弱实现,这可能就足够了。因此,如果您能够构建一个神经网络,以55%的成功率预测PRNG的下一阶段(被认为是安全的密码术),那么您可能会在相当长的一段时间内成为安全新闻的头条新闻。
作为机器学习的新手,我做了这个实验(使用Scikit-learn):
使用python random.choices函数从90个数字中选择N个,生成了大量(N)个伪随机抽取。
使用以下组成的训练数据训练了MLP分类器:
在实践中,我的目标是给定N个数字的函数,可以预测下一个。
让训练有素的分类器预测剩余数量。
结果:
当然,分类器获得的获胜分数与随机猜测或非基于神经网络的其他技术之一相当(我将结果与scikit-learn库中的几种分类器进行了比较)
但是,如果我生成具有特定分布函数的伪随机抽奖,则由神经网络预测的数字将使用相同的分布曲线大致生成(如果您绘制随机数和神经网络预测的出现,您可以看到,即使在预测曲线中有许多尖峰,两者的趋势也相同,因此神经网络也许能够了解伪随机数分布?
如果我将训练集的大小减小到一定限度以下,我会看到分类器开始预测总是相同的几个数字,这些数字在伪随机数生成中最频繁。奇怪的是(或者可能不是),这种行为似乎稍微增加了获胜分数。
旧问题,但我认为这是一个实际的答案。在看了如何构建这样的神经网络的指南之后,我偶然发现了它,并以python randint的示例为例。这是没有详细说明的最终代码,在链接脱机的情况下仍然非常简单和有用:
from random import randint
from numpy import array
from numpy import argmax
from pandas import concat
from pandas import DataFrame
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
# generate a sequence of random numbers in [0, 99]
def generate_sequence(length=25):
return [randint(0, 99) for _ in range(length)]
# one hot encode sequence
def one_hot_encode(sequence, n_unique=100):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
# generate data for the lstm
def generate_data():
# generate sequence
sequence = generate_sequence()
# one hot encode
encoded = one_hot_encode(sequence)
# create lag inputs
df = DataFrame(encoded)
df = concat([df.shift(4), df.shift(3), df.shift(2), df.shift(1), df], axis=1)
# remove non-viable rows
values = df.values
values = values[5:,:]
# convert to 3d for input
X = values.reshape(len(values), 5, 100)
# drop last value from y
y = encoded[4:-1,:]
return X, y
# define model
model = Sequential()
model.add(LSTM(50, batch_input_shape=(5, 5, 100), stateful=True))
model.add(Dense(100, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
# fit model
for i in range(2000):
X, y = generate_data()
model.fit(X, y, epochs=1, batch_size=5, verbose=2, shuffle=False)
model.reset_states()
# evaluate model on new data
X, y = generate_data()
yhat = model.predict(X, batch_size=5)
print('Expected: %s' % one_hot_decode(y))
print('Predicted: %s' % one_hot_decode(yhat))
我刚刚尝试过,它的确运行良好!在旧的慢速上网本上只花了几分钟。这是我自己的输出,与上面的链接不同,您可以看到匹配不是完美的,所以我认为退出条件有点宽松:
...
- 0s - loss: 0.2545 - acc: 1.0000
Epoch 1/1
- 0s - loss: 0.1845 - acc: 1.0000
Epoch 1/1
- 0s - loss: 0.3113 - acc: 0.9500
Expected: [14, 37, 0, 65, 30, 7, 11, 6, 16, 19, 68, 4, 25, 2, 79, 45, 95, 92, 32, 33]
Predicted: [14, 37, 0, 65, 30, 7, 11, 6, 16, 19, 68, 4, 25, 2, 95, 45, 95, 92, 32, 33]
如果伪随机数生成器抛出了数字,那么在分析这些数字时,您将能够确定产生这些数字的算法,因为数字不是随机的,而是由该算法确定的,并且不是偶然的。如果世界由能够被理解和复制的物理定律组成,那么我们在事件中观察到的明显随机性将取决于那些物理定律。伪生成器不再存在,而是实际的随机性,根据其定义是不确定的,并呈现出悖论。规则如何通过定义来确定随机性,可以肯定的是,我们对观察到的事件的随机性的明显认识只是一种暗示,实际上是我们无法预测的确定性。
除了Demento所说的之外,随机数生成算法中的随机性程度是关键问题。以下是一些可能会使RNG变弱的设计:
隐式序列
假设这是前面生成的几个字符序列:(仅示例,为实际使用,使用了较大的范围)
lwjVJA
Ls3Ajg
xpKr+A
XleXYg
9hyCzA
jeFuNg
JaZZoA
最初,您无法观察到世代中的任何模式,但是将它们更改为Base64编码,然后更改为十六进制,我们得到以下信息:
9708D524
2ECDC08E
C692ABF8
5E579762
F61C82CC
8DE16E36
25A659A0
现在,如果我们从前一个数字中减去每个数字,我们将得到:
FF97C4EB6A
97C4EB6A
FF97C4EB6A
97C4EB6A
FF97C4EB6A
FF97C4EB6A
这表明该算法仅将0x97C4EB6A添加到先前的值,将结果截断为32位数字,然后对数据进行Base64编码。
以上是一个基本示例。当今的ML算法和系统具有足够的能力来学习和预测更复杂的模式。
时间依赖性
一些RNG算法使用时间作为生成随机数的主要输入,尤其是开发人员自己创建的,用于应用程序中的随机数。
只要实现了随机的弱RNG算法,就可以在有足够数据集的情况下以完美的精度向前或向后推断它们。