zoukankan      html  css  js  c++  java
  • java随机数

    一.Math.random()

    产生的随机数是 0 - 1 之间的一个 double,即 0 <= random <= 1

            for (int i = 0; i < 5; i++) {
                System.out.println(Math.random());
            }

     实现原理:

    When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression new java.util.Random(),This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.

    当第一次调用 Math.random() 方法时,自动创建了一个伪随机数生成器,实际上用的是 new java.util.Random()。当接下来继续调用 Math.random() 方法时,就会使用这个新的伪随机数生成器

        public static double random() {
            return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
        }
        private static final class RandomNumberGeneratorHolder {
            static final Random randomNumberGenerator = new Random();
        }
    * <p>This method is properly synchronized to allow correct use by
    * more than one thread. However, if many threads need to generate
    * pseudorandom numbers at a great rate, it may reduce contention
    * for each thread to have its own pseudorandom-number generator.

    在多线程情况下,只有一个线程会负责创建伪随机数生成器(使用当前时间作为种子),其他线程则利用该伪随机数生成器产生随机数。

    因此 Math.random() 方法是线程安全的。

    二.java.util.Random 工具类

    在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,他可以产生随机整数、随机float、随机double,随机long,这个也是我们在j2me的程序里经常用的一个取随机数的方法。

    查看javadoc

     * An instance of this class is used to generate a stream of
     * pseudorandom numbers. The class uses a 48-bit seed, which is
     * modified using a linear congruential formula. (See Donald Knuth,
     * <i>The Art of Computer Programming, Volume 2</i>, Section 3.2.1.)

    基本算法:linear congruential pseudorandom number generator (LGC) 线性同余法伪随机数生成器

    缺点:可预测

    An attacker will simply compute the seed from the output values observed. This takes significantly less time than 2^48 in the case of java.util.Random.
    从输出中可以很容易计算出种子值。
    It is shown that you can predict future Random outputs observing only two(!) output values in time roughly 2^16.
    因此可以预测出下一个输出的随机数。
    You should never use an LCG for security-critical purposes.
    在注重信息安全的应用中,不要使用 LCG 算法生成随机数,请使用 SecureRandom。
     
    Random类提供的方法:API
    • nextBoolean() - 返回均匀分布的 true 或者 false
    • nextBytes(byte[] bytes)
    • nextDouble() - 返回 0.0 到 1.0 之间的均匀分布的 double
    • nextFloat() - 返回 0.0 到 1.0 之间的均匀分布的 float
    • nextGaussian()- 返回 0.0 到 1.0 之间的高斯分布(即正态分布)的 double
    • nextInt() - 返回均匀分布的 int
    • nextInt(int n) - 返回 0 到 n 之间的均匀分布的 int (包括 0,不包括 n)
    • nextLong() - 返回均匀分布的 long
    • setSeed(long seed) - 设置种子

    java.util.Random类有两种方式构建方式:

    1. 带种子
    2. 不带种子(类默认使用当前系统时钟作为种子)

    只要种子一样,产生的随机数也一样: 因为种子确定,随机数算法也确定,因此输出是确定的

            Random random1 = new Random(10000);
            Random random2 = new Random(10000);
            for (int i = 0; i < 5; i++) {
                System.out.println(random1.nextInt() + " = " + random2.nextInt());
            }

    三.java.util.concurrent.ThreadLocalRandom工具类

    ThreadLocalRandom 是 JDK 7 之后提供,也是继承至 java.util.Random。

    每一个线程有一个独立的随机数生成器,用于并发产生随机数,能够解决多个线程发生的竞争争夺。效率更高!

    ThreadLocalRandom 不是直接用 new 实例化,而是第一次使用其静态方法 current() 得到 ThreadLocal<ThreadLocalRandom> 实例,然后调用 java.util.Random 类提供的方法获得各种随机数

        class MyThread extends Thread {
            @Override
            public void run() {
                for (int i = 0; i < 2; i++) {
                    System.out.println(Thread.currentThread().getName() + ": " + ThreadLocalRandom.current().nextDouble());
                }
            }
        }

    四.java.Security.SecureRandom

    也是继承至 java.util.RandomInstances of java.util.Random are not cryptographically secure. Consider instead using SecureRandom to get a cryptographically secure pseudo-random number generator for use by security-sensitive applications.

    SecureRandom takes Random Data from your os (they can be interval between keystrokes etc - most os collect these data store them in files - /dev/random and /dev/urandom in case of linux/solaris) and uses that as the seed.
    操作系统收集了一些随机事件,比如鼠标点击,键盘点击等等,SecureRandom 使用这些随机事件作为种子。
    • SecureRandom 提供加密的强随机数生成器 (RNG),要求种子必须是不可预知的,产生非确定性输出。
    • SecureRandom 也提供了与实现无关的算法,因此,调用方(应用程序代码)会请求特定的 RNG 算法并将它传回到该算法的 SecureRandom 对象中。
    如果仅指定算法名称,如下所示:
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

    如果既指定了算法名称又指定了包提供程序,如下所示:

    SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            SecureRandom ng = SecureRandom.getInstance("SHA1PRNG");
    
            byte[] randomBytes = new byte[16];
            ng.nextBytes(randomBytes);
            System.out.println(randomBytes);
    
            for (int i = 0; i < 10; i++) {
                System.out.println(ng.nextInt());
            }
    在使用SecureRandom的时候可以设置熵池策略,如果设置不对,可能造成一些问题

    jdbc连接oracle Connection reset异常

    springboot应用连接oracle数据库报错connection reset;errorcode 17002 state 08006

    Java 随机数 Random VS SecureRandom 
  • 相关阅读:
    【Lintcode】112.Remove Duplicates from Sorted List
    【Lintcode】087.Remove Node in Binary Search Tree
    【Lintcode】011.Search Range in Binary Search Tree
    【Lintcode】095.Validate Binary Search Tree
    【Lintcode】069.Binary Tree Level Order Traversal
    【Lintcode】088.Lowest Common Ancestor
    【Lintcode】094.Binary Tree Maximum Path Sum
    【算法总结】二叉树
    库(静态库和动态库)
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/grasp/p/12698881.html
Copyright © 2011-2022 走看看