Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这段代码使用随机字符串打印;“你好,世界”吗;?_Java_String_Random - Fatal编程技术网

Java 为什么这段代码使用随机字符串打印;“你好,世界”吗;?

Java 为什么这段代码使用随机字符串打印;“你好,世界”吗;?,java,string,random,Java,String,Random,下面的print语句将打印“helloworld”。 有人能解释一下吗 System.out.println(randomString(-229985452) + " " + randomString(-147909649)); 而randomString()如下所示: public static String randomString(int i) { Random ran = new Random(i); StringBuilder sb = new StringBuild

下面的print语句将打印“helloworld”。 有人能解释一下吗

System.out.println(randomString(-229985452) + " " + randomString(-147909649));
randomString()
如下所示:

public static String randomString(int i)
{
    Random ran = new Random(i);
    StringBuilder sb = new StringBuilder();
    while (true)
    {
        int k = ran.nextInt(27);
        if (k == 0)
            break;

        sb.append((char)('`' + k));
    }

    return sb.toString();
}

当使用特定种子参数构造
java.util.Random
的实例时(在本例中为
-229985452
-147909649
),它遵循从该种子值开始的随机数生成算法


每个用相同种子构建的
Random
每次都将生成相同的数字模式。

Random始终返回相同的序列。它用于洗牌数组和其他置换操作

要获得不同的序列,必须在称为“种子”的位置初始化序列

randomSting获取“random”序列的i位置(seed=-229985452)的随机数。然后对种子位置后的序列中的下一个27个字符使用代码,直到该值等于0。这将返回“你好”。同样的操作也适用于“世界”

我认为代码对其他任何词都不起作用。那个编程的人对随机序列非常熟悉


这是非常棒的极客代码

其他答案解释了原因,但下面是如何解释的

给定一个
随机
的实例:

Random r = new Random(-229985452)
r.nextInt(27)
生成的前6个数字是:

8
5
12
12
15
0
r.nextInt(27)
生成给定
Random r=new Random(-147909649)
的前6个数字是:

23
15
18
12
4
0
然后只需将这些数字添加到字符
`
的整数表示形式(即96):


我就把它留在这里。无论谁有很多(CPU)空闲时间,都可以自由尝试:)另外,如果你已经掌握了一些fork-join-fu来让这个东西烧掉所有的CPU核心(只是线程很无聊,对吧?),请分享你的代码。我将不胜感激

public static void main(String[] args) {
    long time = System.currentTimeMillis();
    generate("stack");
    generate("over");
    generate("flow");
    generate("rulez");

    System.out.println("Took " + (System.currentTimeMillis() - time) + " ms");
}

private static void generate(String goal) {
    long[] seed = generateSeed(goal, Long.MIN_VALUE, Long.MAX_VALUE);
    System.out.println(seed[0]);
    System.out.println(randomString(seed[0], (char) seed[1]));
}

public static long[] generateSeed(String goal, long start, long finish) {
    char[] input = goal.toCharArray();
    char[] pool = new char[input.length];
    label:
    for (long seed = start; seed < finish; seed++) {
        Random random = new Random(seed);

        for (int i = 0; i < input.length; i++)
            pool[i] = (char) random.nextInt(27);

        if (random.nextInt(27) == 0) {
            int base = input[0] - pool[0];
            for (int i = 1; i < input.length; i++) {
                if (input[i] - pool[i] != base)
                    continue label;
            }
            return new long[]{seed, base};
        }

    }

    throw new NoSuchElementException("Sorry :/");
}

public static String randomString(long i, char base) {
    System.out.println("Using base: '" + base + "'");
    Random ran = new Random(i);
    StringBuilder sb = new StringBuilder();
    for (int n = 0; ; n++) {
        int k = ran.nextInt(27);
        if (k == 0)
            break;

        sb.append((char) (base + k));
    }

    return sb.toString();
}

我编写了一个快速程序来查找这些种子:

import java.lang.*;
import java.util.*;
import java.io.*;

public class RandomWords {
    public static void main (String[] args) {
        Set<String> wordSet = new HashSet<String>();
        String fileName = (args.length > 0 ? args[0] : "/usr/share/dict/words");
        readWordMap(wordSet, fileName);
        System.err.println(wordSet.size() + " words read.");
        findRandomWords(wordSet);
    }

    private static void readWordMap (Set<String> wordSet, String fileName) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(fileName));
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim().toLowerCase();
                if (isLowerAlpha(line)) wordSet.add(line);
            }
        }
        catch (IOException e) {
            System.err.println("Error reading from " + fileName + ": " + e);
        }
    }

    private static boolean isLowerAlpha (String word) {
        char[] c = word.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] < 'a' || c[i] > 'z') return false;
        }
        return true;
    }

    private static void findRandomWords (Set<String> wordSet) {
        char[] c = new char[256];
        Random r = new Random();
        for (long seed0 = 0; seed0 >= 0; seed0++) {
            for (int sign = -1; sign <= 1; sign += 2) {
                long seed = seed0 * sign;
                r.setSeed(seed);
                int i;
                for (i = 0; i < c.length; i++) {
                    int n = r.nextInt(27);
                    if (n == 0) break;
                    c[i] = (char)((int)'a' + n - 1);
                }
                String s = new String(c, 0, i);
                if (wordSet.contains(s)) {
                    System.out.println(s + ": " + seed);
                    wordSet.remove(s);
                }
            }
        }
    }
}
import java.lang.*;
导入java.util.*;
导入java.io.*;
公共类随机词{
公共静态void main(字符串[]args){
Set wordSet=newhashset();
字符串文件名=(args.length>0?args[0]:“/usr/share/dict/words”);
readWordMap(字集,文件名);
System.err.println(wordSet.size()+“words read”);
findRandomWords(单词集);
}
私有静态void readWordMap(设置字集,字符串文件名){
试一试{
BufferedReader reader=新的BufferedReader(新文件读取器(文件名));
弦线;
而((line=reader.readLine())!=null){
line=line.trim().toLowerCase();
if(islowerapha(line))wordSet.add(line);
}
}
捕获(IOE异常){
System.err.println(“读取“+fileName+”:“+e”时出错);
}
}
私有静态布尔ISLOWRALPHA(字符串字){
char[]c=word.toCharArray();
for(int i=0;i'z')返回false;
}
返回true;
}
私有静态void findRandomWords(Set wordSet){
char[]c=新字符[256];
随机r=新随机();
for(长seed0=0;seed0>=0;seed0++){

对于(int sign=-1;sign这里的每个人都做了大量的工作,解释了代码是如何工作的,并展示了如何构建自己的示例,但这里有一个信息理论的答案,说明了为什么我们可以合理地期待暴力搜索最终会找到一个解决方案

26个不同的小写字母构成了我们的字母表
。为了生成不同长度的单词,我们进一步添加了终止符
生成扩展字母表
∑':=∑∪ {⊥}

α
为符号,X为
上均匀分布的随机变量。获得该符号的概率p(X=α)
及其信息内容I(α)
由下式给出:

p(X=α)=1/|∑‘|=1/27

I(α)=-log₂[P(X=α)]=-log₂(1/27)=对数₂(27)

对于一个单词
ω∈ ∑*
及其
⊥-终止的对应方<代码>ω':=ω·⊥ ∈ (∑’)*
,我们有

I(ω):=I(ω’=|ω’|*log₂(27)=(ω+1)*log₂(27)

由于伪随机数生成器(PRNG)是用32位种子初始化的,因此我们可以预期大多数字的长度为

λ=地板[32/对数₂(27)]-1=5

至少由一个种子生成。即使我们要搜索一个6个字符的单词,我们仍然会在大约41.06%的时间内成功。不太糟糕

对于7封信,我们看到接近1.52%,但在尝试之前,我还没有意识到:

#include <iostream>
#include <random>
 
int main()
{
    std::mt19937 rng(631647094);
    std::uniform_int_distribution<char> dist('a', 'z' + 1);
 
    char alpha;
    while ((alpha = dist(rng)) != 'z' + 1)
    {
        std::cout << alpha;
    }
}
#包括
#包括
int main()
{
标准:mt19937 rng(631647094);
标准:统一分布区('a','z'+1);
炭α;
而((alpha=dist(rng))!='z'+1)
{

实际上,大多数随机数生成器是“伪随机的”。它们是线性同余生成器,或LCG()


如果有一个固定的种子,LCG是可以预测的。基本上,使用一个种子给你第一个字母,然后编写一个应用程序,继续生成下一个int(char)直到找到目标字符串中的下一个字母,并记下调用LCG的次数。继续,直到生成每个字母。

从Java文档中,这是为Random类指定种子值时有意使用的功能

如果使用同一种子创建了两个Random实例,则 对每个方法调用的顺序相同,它们将生成 返回相同的数字序列。为了保证这一点 属性,则为Random类指定了特定的算法。 Java实现必须使用此处所示的所有算法 氯
import java.lang.*;
import java.util.*;
import java.io.*;

public class RandomWords {
    public static void main (String[] args) {
        Set<String> wordSet = new HashSet<String>();
        String fileName = (args.length > 0 ? args[0] : "/usr/share/dict/words");
        readWordMap(wordSet, fileName);
        System.err.println(wordSet.size() + " words read.");
        findRandomWords(wordSet);
    }

    private static void readWordMap (Set<String> wordSet, String fileName) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(fileName));
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim().toLowerCase();
                if (isLowerAlpha(line)) wordSet.add(line);
            }
        }
        catch (IOException e) {
            System.err.println("Error reading from " + fileName + ": " + e);
        }
    }

    private static boolean isLowerAlpha (String word) {
        char[] c = word.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] < 'a' || c[i] > 'z') return false;
        }
        return true;
    }

    private static void findRandomWords (Set<String> wordSet) {
        char[] c = new char[256];
        Random r = new Random();
        for (long seed0 = 0; seed0 >= 0; seed0++) {
            for (int sign = -1; sign <= 1; sign += 2) {
                long seed = seed0 * sign;
                r.setSeed(seed);
                int i;
                for (i = 0; i < c.length; i++) {
                    int n = r.nextInt(27);
                    if (n == 0) break;
                    c[i] = (char)((int)'a' + n - 1);
                }
                String s = new String(c, 0, i);
                if (wordSet.contains(s)) {
                    System.out.println(s + ": " + seed);
                    wordSet.remove(s);
                }
            }
        }
    }
}
import java.lang.*;
import java.util.*;

public class RandomWordsTest {
    public static void main (String[] args) {
        long[] a = {-73, -157512326, -112386651, 71425, -104434815,
                    -128911, -88019, -7691161, 1115727};
        for (int i = 0; i < a.length; i++) {
            Random r = new Random(a[i]);
            StringBuilder sb = new StringBuilder();
            int n;
            while ((n = r.nextInt(27)) > 0) sb.append((char)('`' + n));
            System.out.println(sb);
        }
    }
}
#include <iostream>
#include <random>
 
int main()
{
    std::mt19937 rng(631647094);
    std::uniform_int_distribution<char> dist('a', 'z' + 1);
 
    char alpha;
    while ((alpha = dist(rng)) != 'z' + 1)
    {
        std::cout << alpha;
    }
}
public static long generateSeed(String goal, long start, long finish) {
    char[] input = goal.toCharArray();
    char[] pool = new char[input.length];
    label:
        for (long seed = start; seed < finish; seed++) {
            Random random = new Random(seed);

            for (int i = 0; i < input.length; i++)
                pool[i] = (char) (random.nextInt(27)+'`');

            if (random.nextInt(27) == 0) {
                for (int i = 0; i < input.length; i++) {
                    if (input[i] != pool[i])
                        continue label;
                }
                return seed;
            }

        }

    throw new NoSuchElementException("Sorry :/");
}
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class SeedFinder {

  static class SearchTask implements Callable<Long> {

    private final char[] goal;
    private final long start, step;

    public SearchTask(final String goal, final long offset, final long step) {
      final char[] goalAsArray = goal.toCharArray();
      this.goal = new char[goalAsArray.length + 1];
      System.arraycopy(goalAsArray, 0, this.goal, 0, goalAsArray.length);
      this.start = Long.MIN_VALUE + offset;
      this.step = step;
    }

    @Override
    public Long call() throws Exception {
      final long LIMIT = Long.MAX_VALUE - this.step;
      final Random random = new Random();
      int position, rnd;
      long seed = this.start;

      while ((Thread.interrupted() == false) && (seed < LIMIT)) {
        random.setSeed(seed);
        position = 0;
        rnd = random.nextInt(27);
        while (((rnd == 0) && (this.goal[position] == 0))
                || ((char) ('`' + rnd) == this.goal[position])) {
          ++position;
          if (position == this.goal.length) {
            return seed;
          }
          rnd = random.nextInt(27);
        }
        seed += this.step;
      }

      throw new Exception("No match found");
    }
  }

  public static void main(String[] args) {
    final String GOAL = "hello".toLowerCase();
    final int NUM_CORES = Runtime.getRuntime().availableProcessors();

    final ArrayList<SearchTask> tasks = new ArrayList<>(NUM_CORES);
    for (int i = 0; i < NUM_CORES; ++i) {
      tasks.add(new SearchTask(GOAL, i, NUM_CORES));
    }

    final ExecutorService executor = Executors.newFixedThreadPool(NUM_CORES, new ThreadFactory() {

      @Override
      public Thread newThread(Runnable r) {
        final Thread result = new Thread(r);
        result.setPriority(Thread.MIN_PRIORITY); // make sure we do not block more important tasks
        result.setDaemon(false);
        return result;
      }
    });
    try {
      final Long result = executor.invokeAny(tasks);
      System.out.println("Seed for \"" + GOAL + "\" found: " + result);
    } catch (Exception ex) {
      System.err.println("Calculation failed: " + ex);
    } finally {
      executor.shutdownNow();
    }
  }
}
int[] arrInt = {-2146926310, -1885533740, -274140519, 
                -2145247212, -1845077092, -2143584283,
                -2147483454, -2138225126, -2147375969};

for(int seed : arrInt){
    System.out.print(randomString(seed) + " ");
}
the quick browny fox jumps over a lazy dog 
public static long[] generateSeed(String goal, long start, long finish) {
    char[] input = goal.toCharArray();

    int[] dif = new int[input.length - 1];
    for (int i = 1; i < input.length; i++) {
        dif[i - 1] = input[i] - input[i - 1];
    }

    mainLoop:
    for (long seed = start; seed < finish; seed++) {
        Random random = new Random(seed);
        int lastChar = random.nextInt(27);
        int base = input[0] - lastChar;
        for (int d : dif) {
            int nextChar = random.nextInt(27);
            if (nextChar - lastChar != d) {
                continue mainLoop;
            }
            lastChar = nextChar;
        }
        if(random.nextInt(27) == 0){
            return new long[]{seed, base};
        }
    }

    throw new NoSuchElementException("Sorry :/");
}
public static void main(String[] args) {

    randomString(-229985452);
    System.out.println("------------");
    randomString(-229985452);

}

private static void randomString(int i) {
    Random ran = new Random(i);
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());

}
-755142161
-1073255141
-369383326
1592674620
-1524828502
------------
-755142161
-1073255141
-369383326
1592674620
-1524828502