问题是,为什么在单独的方法调用中获取相同数量的字节的行为返回不同的字节,这取决于在单个方法调用中调用的5000个字节或者使用长度为1的字节数组进行5000个方法调用。
采用以下示例:在终端中打印21而不是5000,(5000除以256得到~19,这使得21次匹配很可能是简单的巧合)。
Random rand = new Random(0);
byte tmp1[] = new byte[5000];
rand.nextBytes(tmp1);
rand = new Random(0);
byte tmp2[] = new byte[5000];
byte tmp3[] = new byte[1];
for(int i = 0; i < 5000;i++)
{
rand.nextBytes(tmp3);
tmp2[i] =tmp3[0];
}
int matches = 0;
for(int i = 0; i < 5000;i++)
{
if(tmp1[i] == tmp2[i])
{
matches++;
}
}
System.out.println(matches);
更重要的是,任何破解它生成相同字节的方法与我是否使用长度为5000的数组或长度为2500的数组两次调用方法无关。
编辑:下面的帖子完美地回答了问题,一次接收字节4完全解决了问题。测试代码如下,返回4000:
Random rand1 = new Random(0);
byte tmp11[] = new byte[4000];
rand1.nextBytes(tmp11);
rand1 = new Random(0);
byte tmp22[] = new byte[4000];
byte tmp33[] = new byte[4];
for(int i = 0; i < 1000;i++)
{
rand1.nextBytes(tmp33);
for(int a = 0; a < 4;a++)
{
tmp22[(i*4)+a] = tmp33[a];
}
}
int matches1 = 0;
for(int i = 0; i < 4000;i++)
{
if(tmp11[i] == tmp22[i])
{
matches1++;
}
}
System.out.println(matches1);
那是因为java使用nextInt()来填充字节,并将其他3个int值字节添加到数组中。基本上,从随机生成器接收的每个int填充4个字节的数组。我将添加一个例子。
这是javadoc的第一个:
方法nextBytes由Random类实现,如下所示:
public void nextBytes(byte[] bytes) { for (int i = 0; i < bytes.length; ) for (int rnd = nextInt(), n = Math.min(bytes.length - i, 4); n-- > 0; rnd >>= 8) bytes[i++] = (byte)rnd; }
所以现在要展示我们可以做的例子:
Random rand = new Random(0);
rand.nextBytes(tmp1);
System.out.println(tmp1[0]);
System.out.println(tmp1[4]);
rand = new Random(0);
rand.nextBytes(tmp3);
System.out.println(tmp3[0]);
rand.nextBytes(tmp3);
System.out.println(tmp3[0]);
打印:96 56 96 56因为int的大小是4.基本上它得到一个int(4个字节)并将它添加到位置0,1,2,3中的字节数组。当你用byte [1]调用它时,它获得相同的int并将相同的字节添加到值0,但int中的其他3个字节将丢失。这就是你不一致的原因。你得到的数字21只是巧合。
由于java的Random
是伪随机数生成器,因此每次调用任何next
方法时,其内部“状态”将前进,即将返回可能与前一个不同的伪随机数。结合nextBytes
的描述,该描述表明它为目标字节数组中的每4个字节从一次调用nextInt
构造目标字节数组,这会导致代码的结果不同。