⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 randomdataimpl.java

📁 Apache的common math数学软件包
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.math.random;import java.io.Serializable;import java.security.MessageDigest;import java.security.SecureRandom;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.util.Collection;/** * Implements the {@link RandomData} interface using a {@link RandomGenerator} * instance to generate non-secure data and a  * {@link java.security.SecureRandom} instance to provide data for the * <code>nextSecureXxx</code> methods.  If no <code>RandomGenerator</code> * is provided in the constructor, the default is to use a generator based on * {@link java.util.Random}.   To plug in a different implementation,  * either implement <code>RandomGenerator</code> directly or extend * {@link AbstractRandomGenerator}. * <p> * Supports reseeding the underlying pseudo-random number generator (PRNG).  * The <code>SecurityProvider</code> and <code>Algorithm</code> * used by the <code>SecureRandom</code> instance can also be reset.</p> * <p> * For details on the default PRNGs, see {@link java.util.Random} and * {@link java.security.SecureRandom}.</p> * <p> * <strong>Usage Notes</strong>: <ul> * <li> * Instance variables are used to maintain <code>RandomGenerator</code> and * <code>SecureRandom</code> instances used in data generation. Therefore, * to generate a random sequence of values or strings, you should use just * <strong>one</strong> <code>RandomDataImpl</code> instance repeatedly.</li> * <li> * The "secure" methods are *much* slower.  These should be used only when a * cryptographically secure random sequence is required.  A secure random * sequence is a sequence of pseudo-random values which, in addition to being * well-dispersed (so no subsequence of values is an any more likely than other * subsequence of the the same length), also has the additional property that * knowledge of values generated up to any point in the sequence does not make * it any easier to predict subsequent values.</li> * <li> * When a new <code>RandomDataImpl</code> is created, the underlying random * number generators are <strong>not</strong> intialized.  If you do not * explicitly seed the default non-secure generator, it is seeded with the current time * in milliseconds on first use.  The same holds for the secure generator.   * If you provide a <code>RandomGenerator</code> to the constructor, however, * this generator is not reseeded by the constructor nor is it reseeded on * first use. </li> * <li> * The <code>reSeed</code> and <code>reSeedSecure</code> methods delegate * to the corresponding methods on the underlying <code>RandomGenerator</code> * and<code>SecureRandom</code> instances.  Therefore,  * <code>reSeed(long)</code> fully resets the initial state of the non-secure * random number generator (so that reseeding with a specific value always * results in the same subsequent random sequence); whereas reSeedSecure(long) * does <strong>not</strong> reinitialize the secure random number generator * (so secure sequences started with calls to reseedSecure(long) won't be * identical).</li> * <li> * This implementation is not synchronized. * </ul></p> * * @version $Revision: 615734 $ $Date: 2008-01-27 23:10:03 -0700 (Sun, 27 Jan 2008) $ */public class RandomDataImpl implements RandomData, Serializable {    /** Serializable version identifier */    private static final long serialVersionUID = -626730818244969716L;    /** underlying random number generator */    private RandomGenerator rand = null;    /** underlying secure random number generator */    private SecureRandom secRand = null;    /**     * Construct a RandomDataImpl.     */    public RandomDataImpl() {    }        /**     * Construct a RandomDataImpl using the supplied {@link RandomGenerator}     * as the source of (non-secure) random data.     *      * @param rand  the source of (non-secure) random data     * @since 1.1     */    public RandomDataImpl(RandomGenerator rand) {        super();        this.rand = rand;    }    /**     * {@inheritDoc}<p>     * <strong>Algorithm Description:</strong> hex strings are generated     * using a 2-step process. <ol>     * <li>     * len/2+1 binary bytes are generated using the underlying Random</li>     * <li>     * Each binary byte is translated into 2 hex digits</li></ol></p>     *      * @param len the desired string length.     * @return the random string.     */    public String nextHexString(int len) {        if (len <= 0) {            throw new IllegalArgumentException("length must be positive");        }        //Get a random number generator        RandomGenerator ran = getRan();        //Initialize output buffer        StringBuffer outBuffer = new StringBuffer();        //Get int(len/2)+1 random bytes        byte[] randomBytes = new byte[(len / 2) + 1];        ran.nextBytes(randomBytes);        //Convert each byte to 2 hex digits        for (int i = 0; i < randomBytes.length; i++) {            Integer c = new Integer(randomBytes[i]);            /* Add 128 to byte value to make interval 0-255 before             * doing hex conversion.             * This guarantees <= 2 hex digits from toHexString()             * toHexString would otherwise add 2^32 to negative arguments.             */             String hex = Integer.toHexString(c.intValue() + 128);             // Make sure we add 2 hex digits for each byte             if (hex.length() == 1)  {                 hex = "0" + hex;             }             outBuffer.append(hex);        }        return outBuffer.toString().substring(0, len);    }    /**     * Generate a random int value uniformly distributed between     * <code>lower</code> and <code>upper</code>, inclusive.     *      * @param lower the lower bound.     * @param upper the upper bound.     * @return the random integer.     */    public int nextInt(int lower, int upper) {        if (lower >= upper) {            throw new IllegalArgumentException                ("upper bound must be > lower bound");        }        RandomGenerator rand = getRan();        double r = rand.nextDouble();        return (int)((r * upper) + ((1.0 - r) * lower) + r);    }    /**     * Generate a random long value uniformly distributed between     * <code>lower</code> and <code>upper</code>, inclusive.     *      * @param lower the lower bound.     * @param upper the upper bound.     * @return the random integer.     */    public long nextLong(long lower, long upper) {        if (lower >= upper) {            throw new IllegalArgumentException                ("upper bound must be > lower bound");        }        RandomGenerator rand = getRan();        double r = rand.nextDouble();        return (long)((r * upper) + ((1.0 - r) * lower) + r);    }     /**     * {@inheritDoc}<p>     * <strong>Algorithm Description:</strong> hex strings are generated in     * 40-byte segments using a 3-step process. <ol>     * <li>     * 20 random bytes are generated using the underlying     * <code>SecureRandom</code>.</li>     * <li>     * SHA-1 hash is applied to yield a 20-byte binary digest.</li>     * <li>     * Each byte of the binary digest is converted to 2 hex digits.</li></ol>     * </p>     *     * @param len the length of the generated string     * @return the random string     */    public String nextSecureHexString(int len) {        if (len <= 0) {            throw new IllegalArgumentException("length must be positive");        }       // Get SecureRandom and setup Digest provider       SecureRandom secRan = getSecRan();       MessageDigest alg = null;       try {            alg = MessageDigest.getInstance("SHA-1");       } catch (NoSuchAlgorithmException ex) {           return null; // gulp FIXME? -- this *should* never fail.       }       alg.reset();       //Compute number of iterations required (40 bytes each)       int numIter = (len / 40) + 1;       StringBuffer outBuffer = new StringBuffer();       for (int iter = 1; iter < numIter + 1; iter++) {            byte[] randomBytes = new byte[40];            secRan.nextBytes(randomBytes);            alg.update(randomBytes);            //Compute hash -- will create 20-byte binary hash            byte hash[] = alg.digest();            //Loop over the hash, converting each byte to 2 hex digits            for (int i = 0; i < hash.length; i++) {                Integer c = new Integer(hash[i]);                /* Add 128 to byte value to make interval 0-255                 * This guarantees <= 2 hex digits from toHexString()                 * toHexString would otherwise add 2^32 to negative                 * arguments                 */                String hex = Integer.toHexString(c.intValue() + 128);               //Keep strings uniform length -- guarantees 40 bytes                if (hex.length() == 1) {                    hex = "0" + hex;                }               outBuffer.append(hex);            }        }        return outBuffer.toString().substring(0, len);    }    /**     * Generate a random int value uniformly distributed between     * <code>lower</code> and <code>upper</code>, inclusive.  This algorithm     * uses a secure random number generator.     *      * @param lower the lower bound.     * @param upper the upper bound.     * @return the random integer.     */    public int nextSecureInt(int lower, int upper) {          if (lower >= upper) {              throw new IllegalArgumentException                ("lower bound must be < upper bound");          }          SecureRandom sec = getSecRan();          return lower + (int) (sec.nextDouble() * (upper - lower + 1));    }    /**     * Generate a random long value uniformly distributed between     * <code>lower</code> and <code>upper</code>, inclusive.  This algorithm     * uses a secure random number generator.     *      * @param lower the lower bound.     * @param upper the upper bound.     * @return the random integer.     */    public long nextSecureLong(long lower, long upper) {        if (lower >= upper) {            throw new IllegalArgumentException            ("lower bound must be < upper bound");        }        SecureRandom sec = getSecRan();        return lower + (long) (sec.nextDouble() * (upper - lower + 1));    }    /**     * {@inheritDoc}     * <p>     * <strong>Algorithm Description</strong>:     * Uses simulation of a Poisson process using Uniform deviates, as     * described     * <a href="http://irmi.epfl.ch/cmos/Pmmi/interactive/rng7.htm">     * here.</a></p>     * <p>     * The Poisson process (and hence value returned) is bounded by 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -