Package propel.core.utils

Source Code of propel.core.utils.RandomUtils

// /////////////////////////////////////////////////////////
// This file is part of Propel.
//
// Propel is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Propel is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Propel. If not, see <http://www.gnu.org/licenses/>.
// /////////////////////////////////////////////////////////
// Authored by: Nikolaos Tountas -> salam.kaser-at-gmail.com
// /////////////////////////////////////////////////////////
package propel.core.utils;

import java.security.SecureRandom;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import lombok.Validate;
import lombok.Validate.NotNull;
import lombok.val;
import propel.core.common.CONSTANT;

/**
* Provides utility functionality for obtaining random data. Please note that the random number generators are not thread safe.
*/
public final class RandomUtils
{
  private static final SecureRandom CRYPTO_RANDOM = new SecureRandom();
  private static final Random PSEUDO_RANDOM = new Random();

  /**
   * Returns a random Int32, created by the information entropy from bytes in a newly created UUID.
   */
  public static int getPseudoInt32()
  {
    val guid = UUID.randomUUID();
    return HashingUtils.uuidToInt32(guid);
  }

  /**
   * Returns a pseudo random within the specified range [min, max) i.e. inclusive minimum and exclusive maximum, created by java.util.Random
   *
   * @throws IllegalArgumentException An argument is out of range
   */
  public static int getPseudoInt32(final int min, final int max)
  {
    if (min < 0)
      throw new IllegalArgumentException("min=" + min);
    if (max < min)
      throw new IllegalArgumentException("max=" + max + " min=" + min);

    return min + PSEUDO_RANDOM.nextInt(max - min);
  }

  /**
   * Returns a random Int64, created by the information entropy from bytes in a newly created UUID.
   */
  public static long getPseudoInt64()
  {
    val guid = UUID.randomUUID();
    return HashingUtils.uuidToInt64(guid);
  }

  /**
   * Returns random bytes, created by the information entropy from bytes in a newly created Guid.
   *
   * @throws IllegalArgumentException An argument is out of range
   */
  public static byte[] getPseudoBytes(final int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("length=" + length);
    if (length == 0)
      return new byte[0];

    val result = new byte[length];
    int index = 0;

    while (true)
    {
      val randomUuid = UUID.randomUUID();
      val random = ByteArrayUtils.getBytes(randomUuid);

      for (int i = 0; i < 16; i++)
      {
        if (index < result.length)
          result[index++] = random[i];
        else
          return result;
      }
    }
  }

  /**
   * Returns random text characters (uses the Base64 set). Randomness sourced from the information entropy of a new UUID.
   *
   * @throws IllegalArgumentException An argument is out of range.
   */
  public static String getPseudoBase64Text(final int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("length=" + length);
    if (length == 0)
      return CONSTANT.EMPTY_STRING;

    val sb = new StringBuilder(length + 32);
    while (sb.length() < length)
      sb.append(ConversionUtils.toBase64(getPseudoInt64()));

    return sb.substring(0, length);
  }

  /**
   * Returns random text characters (uses the 0..9, A..Z and a..z character sets). Randomness sourced from the information entropy of a new
   * UUID.
   *
   * @throws IllegalArgumentException An argument is out of range.
   */
  public static String getPseudoAlphanumericText(final int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("length=" + length);
    if (length == 0)
      return CONSTANT.EMPTY_STRING;

    val sb = new StringBuilder(length + 32);

    while (sb.length() < length)
    {
      val base64 = ConversionUtils.toBase64(getPseudoInt64());
      for (char ch : base64.toCharArray())
        if (Character.isLetterOrDigit(ch))
          sb.append(ch);
    }

    return sb.substring(0, length);
  }

  /**
   * Randomizes elements in an array.
   *
   * @throws NullPointerException An argument is null.
   * @throws IndexOutOfBoundsException An index is out of range.
   */
  @Validate
  public static <T> void pseudoRandomize(@NotNull final T[] data, final int start, final int end)
  {
    if (start < 0 || start >= data.length || start > end)
      throw new IndexOutOfBoundsException("start=" + start + " end=" + end + " dataLen=" + data.length);
    if (end < 0 || end > data.length)
      throw new IndexOutOfBoundsException("end=" + end + " dataLen=" + data.length);

    val from = new int[end - start];
    val to = new int[end - start];
    for (int i = start; i < end; i++)
    {
      from[i] = PSEUDO_RANDOM.nextInt(end - start) + start;
      to[i] = PSEUDO_RANDOM.nextInt(end - start) + start;
    }

    Linq.swap(data, from, to);
  }

  /**
   * Randomizes elements in an array.
   *
   * @throws NullPointerException An argument is null.
   * @throws IndexOutOfBoundsException An index is out of range.
   */
  @Validate
  public static <T> void pseudoRandomize(@NotNull final List<T> data, final int start, final int end)
  {
    if (start < 0 || start >= data.size() || start > end)
      throw new IndexOutOfBoundsException("start=" + start + " end=" + end + " dataLen=" + data.size());
    if (end < 0 || end > data.size())
      throw new IndexOutOfBoundsException("end=" + end + " dataLen=" + data.size());

    val from = new int[end - start];
    val to = new int[end - start];
    for (int i = start; i < end; i++)
    {
      from[i] = PSEUDO_RANDOM.nextInt(end - start) + start;
      to[i] = PSEUDO_RANDOM.nextInt(end - start) + start;
    }

    Linq.swap(data, from, to);
  }

  /**
   * Returns a cryptographically secure random Int32.
   */
  public static int getSecureInt32()
  {
    val buffer = getSecureBytes(4); // size of int
    return ByteArrayUtils.toInt32(buffer);
  }

  /**
   * Returns a cryptographically secure random Int32.
   */
  public static long getSecureInt64()
  {
    val buffer = getSecureBytes(8); // size of long
    return ByteArrayUtils.toInt64(buffer);
  }

  /**
   * Returns a key filled with cryptographically secure random data.
   *
   * @throws IllegalArgumentException An argument is out of range
   */
  public static byte[] getSecureBytes(final int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("length=" + length);
    if (length == 0)
      return new byte[0];

    val buffer = new byte[length];
    CRYPTO_RANDOM.nextBytes(buffer);
    return buffer;
  }

  /**
   * Returns random text characters (uses the Base64 set), created by a cryptographically secure source.
   *
   * @throws IllegalArgumentException An argument is out of range
   */
  public static String getSecureBase64Text(final int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("length=" + length);
    if (length == 0)
      return CONSTANT.EMPTY_STRING;

    val sb = new StringBuilder(length + 32);
    while (sb.length() < length)
      sb.append(ConversionUtils.toBase64(getSecureInt64()));

    return sb.substring(0, length);
  }

  /**
   * Returns random text characters (uses the 0..9, A..Z and a..z character sets) created by a cryptographically secure source.
   *
   * @throws IllegalArgumentException An argument is out of range
   */
  public static String getSecureAlphanumericText(final int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("length=" + length);
    if (length == 0)
      return CONSTANT.EMPTY_STRING;

    val sb = new StringBuilder(length + 32);

    while (sb.length() < length)
    {
      String base64 = ConversionUtils.toBase64(getSecureInt64());
      for (char ch : base64.toCharArray())
        if (Character.isLetterOrDigit(ch))
          sb.append(ch);
    }

    return sb.substring(0, length);
  }

  private RandomUtils()
  {
  }
}
TOP

Related Classes of propel.core.utils.RandomUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.