/*
* Created on Dec 30, 2005
* Created by Alon Rohter
* Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package org.gudy.azureus2.core3.util;
import java.security.SecureRandom;
import java.util.Random;
import org.gudy.azureus2.core3.config.COConfigurationManager;
/**
* @author MjrTom
* 2006/Jan/02: added various methods, including some java.util.Random method aliases
*/
public class
RandomUtils
{
public static final Random RANDOM = new Random( System.currentTimeMillis() );
public static final String INSTANCE_ID;
static{
byte[] bytes = new byte[3];
RANDOM.nextBytes( bytes );
INSTANCE_ID = Base32.encode( bytes ).toLowerCase();
}
public static final SecureRandom SECURE_RANDOM = new SecureRandom();
/**
* Generate a random array of bytes.
* @param num_to_generate number of bytes to generate
* @return random byte array
*/
public static byte[] generateRandomBytes( int num_to_generate ) {
byte[] id = new byte[ num_to_generate ];
RANDOM.nextBytes( id );
return id;
}
/**
* Generate a random string of charactors.
* @param num_to_generate number of chars to generate
* @return random char string
*/
public static String generateRandomAlphanumerics( int num_to_generate ) {
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuffer buff = new StringBuffer( num_to_generate );
for( int i=0; i < num_to_generate; i++ ) {
int pos = (int)( RANDOM.nextDouble() * alphabet.length() );
buff.append( alphabet.charAt( pos ) );
}
return buff.toString();
}
public static final int LISTEN_PORT_MIN = 10000;
public static final int LISTEN_PORT_MAX = 65535;
/**
* Generate a random port number for binding a network IP listening socket to.
* NOTE: Will return a valid non-privileged port number >= LISTEN_PORT_MIN and <= LISTEN_PORT_MAX.
* @return random port number
*/
public static int
generateRandomNetworkListenPort()
{
return( generateRandomNetworkListenPort( LISTEN_PORT_MIN, LISTEN_PORT_MAX ));
}
public static int
generateRandomNetworkListenPort(
int min_port,
int max_port )
{
if ( min_port > max_port ){
int temp = min_port;
min_port = max_port;
max_port = temp;
}
if ( max_port > LISTEN_PORT_MAX ){
max_port = LISTEN_PORT_MAX;
}
if ( max_port < 1 ){
max_port = 1;
}
if ( min_port < 1 ){
min_port = 1;
}
if ( min_port > max_port ){
min_port = max_port;
}
// DON'T use NetworkManager methods to get the ports here else startup can hang
int existing_tcp = COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
int existing_udp = COConfigurationManager.getIntParameter( "UDP.Listen.Port" );
int existing_udp2 = COConfigurationManager.getIntParameter( "UDP.NonData.Listen.Port" );
int port = min_port;
for ( int i=0;i<100;i++ ){
int min = min_port;
port = min + RANDOM.nextInt( max_port + 1 - min );
// skip magnet ports
if ( port >= 45100 && port <= 45110 ){
continue;
}
if ( port != existing_tcp && port != existing_udp && port != existing_udp2){
return port;
}
}
return( port );
}
/**
* Generates a random +1 or -1
* @return +1 or -1
*/
public static int generateRandomPlusMinus1()
{
return RANDOM.nextBoolean() ? -1:1;
}
public static float nextFloat()
{
return RANDOM.nextFloat();
}
public static void nextBytes(byte[] bytes)
{
RANDOM.nextBytes(bytes);
}
public static void nextSecureBytes( byte[] bytes )
{
SECURE_RANDOM.nextBytes( bytes );
}
public static byte[] nextSecureHash()
{
byte[] hash = new byte[20];
SECURE_RANDOM.nextBytes( hash );
return( hash );
}
public static byte[] nextHash()
{
byte[] hash = new byte[20];
RANDOM.nextBytes( hash );
return( hash );
}
public static int nextInt(int n)
{
return RANDOM.nextInt(n);
}
public static byte nextByte()
{
return (byte)RANDOM.nextInt();
}
public static int nextInt()
{
return RANDOM.nextInt();
}
public static int nextAbsoluteInt()
{
return(( RANDOM.nextInt() << 1 ) >>> 1 );
}
public static long nextLong()
{
return RANDOM.nextLong();
}
public static long nextLong( long n )
{
if ( n > Integer.MAX_VALUE ){
while( true ){
long rand = nextAbsoluteLong();
long res = rand % n;
// deal with non-uniformity as rand not generally divisible by n
if ( rand - res + (n-1) >= 0 ){
return( res );
}
}
}
return((long)RANDOM.nextInt((int)n));
}
public static long nextAbsoluteLong()
{
return(( RANDOM.nextLong() << 1 ) >>> 1 );
}
public static long nextSecureAbsoluteLong()
{
while( true ){
long val = Math.abs( SECURE_RANDOM.nextLong());
if ( val >= 0 ){
return( val );
}
}
}
/**
* @return random int between 0 and max-1. e.g. param of 10 returns 0->9
*/
public static int generateRandomIntUpto(int max)
{
return nextInt(max);
}
/**
* @return random int between min and max, e.g params of [5,7] returns 5,6 or 7
*/
public static int generateRandomIntBetween(int min, int max)
{
return min +generateRandomIntUpto(max + 1 - min);
}
}