1 /* 2 * Created on Dec 30, 2005 3 * Created by Alon Rohter 4 * Copyright (C) Azureus Software, Inc, All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 18 */ 19 package org.gudy.azureus2.core3.util; 20 21 import java.security.SecureRandom; 22 import java.util.Random; 23 24 import org.gudy.azureus2.core3.config.COConfigurationManager; 25 26 /** 27 * @author MjrTom 28 * 2006/Jan/02: added various methods, including some java.util.Random method aliases 29 */ 30 31 public class 32 RandomUtils 33 { 34 public static final Random RANDOM = new Random( System.currentTimeMillis() ); 35 36 public static final String INSTANCE_ID; 37 38 static{ 39 byte[] bytes = new byte[3]; 40 41 RANDOM.nextBytes( bytes ); 42 43 INSTANCE_ID = Base32.encode( bytes ).toLowerCase(); 44 } 45 46 public static final SecureRandom SECURE_RANDOM = new SecureRandom(); 47 48 /** 49 * Generate a random array of bytes. 50 * @param num_to_generate number of bytes to generate 51 * @return random byte array 52 */ generateRandomBytes( int num_to_generate )53 public static byte[] generateRandomBytes( int num_to_generate ) { 54 byte[] id = new byte[ num_to_generate ]; 55 RANDOM.nextBytes( id ); 56 return id; 57 } 58 59 60 /** 61 * Generate a random string of charactors. 62 * @param num_to_generate number of chars to generate 63 * @return random char string 64 */ generateRandomAlphanumerics( int num_to_generate )65 public static String generateRandomAlphanumerics( int num_to_generate ) { 66 String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 67 68 StringBuffer buff = new StringBuffer( num_to_generate ); 69 70 for( int i=0; i < num_to_generate; i++ ) { 71 int pos = (int)( RANDOM.nextDouble() * alphabet.length() ); 72 buff.append( alphabet.charAt( pos ) ); 73 } 74 75 return buff.toString(); 76 } 77 78 79 public static final int LISTEN_PORT_MIN = 10000; 80 public static final int LISTEN_PORT_MAX = 65535; 81 82 83 /** 84 * Generate a random port number for binding a network IP listening socket to. 85 * NOTE: Will return a valid non-privileged port number >= LISTEN_PORT_MIN and <= LISTEN_PORT_MAX. 86 * @return random port number 87 */ 88 89 public static int generateRandomNetworkListenPort()90 generateRandomNetworkListenPort() 91 { 92 return( generateRandomNetworkListenPort( LISTEN_PORT_MIN, LISTEN_PORT_MAX )); 93 } 94 95 public static int generateRandomNetworkListenPort( int min_port, int max_port )96 generateRandomNetworkListenPort( 97 int min_port, 98 int max_port ) 99 { 100 if ( min_port > max_port ){ 101 int temp = min_port; 102 min_port = max_port; 103 max_port = temp; 104 } 105 106 if ( max_port > LISTEN_PORT_MAX ){ 107 108 max_port = LISTEN_PORT_MAX; 109 } 110 111 if ( max_port < 1 ){ 112 113 max_port = 1; 114 } 115 116 if ( min_port < 1 ){ 117 118 min_port = 1; 119 } 120 121 if ( min_port > max_port ){ 122 123 min_port = max_port; 124 } 125 126 // DON'T use NetworkManager methods to get the ports here else startup can hang 127 128 int existing_tcp = COConfigurationManager.getIntParameter( "TCP.Listen.Port" ); 129 int existing_udp = COConfigurationManager.getIntParameter( "UDP.Listen.Port" ); 130 int existing_udp2 = COConfigurationManager.getIntParameter( "UDP.NonData.Listen.Port" ); 131 132 int port = min_port; 133 134 for ( int i=0;i<100;i++ ){ 135 int min = min_port; 136 port = min + RANDOM.nextInt( max_port + 1 - min ); 137 138 // skip magnet ports 139 140 if ( port >= 45100 && port <= 45110 ){ 141 142 continue; 143 } 144 145 if ( port != existing_tcp && port != existing_udp && port != existing_udp2){ 146 147 return port; 148 } 149 } 150 151 return( port ); 152 } 153 154 /** 155 * Generates a random +1 or -1 156 * @return +1 or -1 157 */ generateRandomPlusMinus1()158 public static int generateRandomPlusMinus1() 159 { 160 return RANDOM.nextBoolean() ? -1:1; 161 } 162 nextFloat()163 public static float nextFloat() 164 { 165 return RANDOM.nextFloat(); 166 } 167 nextBytes(byte[] bytes)168 public static void nextBytes(byte[] bytes) 169 { 170 RANDOM.nextBytes(bytes); 171 } 172 nextSecureBytes( byte[] bytes )173 public static void nextSecureBytes( byte[] bytes ) 174 { 175 SECURE_RANDOM.nextBytes( bytes ); 176 } 177 nextSecureHash()178 public static byte[] nextSecureHash() 179 { 180 byte[] hash = new byte[20]; 181 182 SECURE_RANDOM.nextBytes( hash ); 183 184 return( hash ); 185 } 186 nextHash()187 public static byte[] nextHash() 188 { 189 byte[] hash = new byte[20]; 190 191 RANDOM.nextBytes( hash ); 192 193 return( hash ); 194 } 195 nextInt(int n)196 public static int nextInt(int n) 197 { 198 return RANDOM.nextInt(n); 199 } 200 nextByte()201 public static byte nextByte() 202 { 203 return (byte)RANDOM.nextInt(); 204 } 205 nextInt()206 public static int nextInt() 207 { 208 return RANDOM.nextInt(); 209 } 210 nextAbsoluteInt()211 public static int nextAbsoluteInt() 212 { 213 return(( RANDOM.nextInt() << 1 ) >>> 1 ); 214 } 215 nextLong()216 public static long nextLong() 217 { 218 return RANDOM.nextLong(); 219 } 220 nextLong( long n )221 public static long nextLong( long n ) 222 { 223 if ( n > Integer.MAX_VALUE ){ 224 225 while( true ){ 226 227 long rand = nextAbsoluteLong(); 228 229 long res = rand % n; 230 231 // deal with non-uniformity as rand not generally divisible by n 232 233 if ( rand - res + (n-1) >= 0 ){ 234 235 return( res ); 236 } 237 } 238 } 239 240 return((long)RANDOM.nextInt((int)n)); 241 } 242 243 nextAbsoluteLong()244 public static long nextAbsoluteLong() 245 { 246 return(( RANDOM.nextLong() << 1 ) >>> 1 ); 247 } 248 nextSecureAbsoluteLong()249 public static long nextSecureAbsoluteLong() 250 { 251 while( true ){ 252 253 long val = Math.abs( SECURE_RANDOM.nextLong()); 254 255 if ( val >= 0 ){ 256 257 return( val ); 258 } 259 } 260 } 261 262 /** 263 * @return random int between 0 and max-1. e.g. param of 10 returns 0->9 264 */ generateRandomIntUpto(int max)265 public static int generateRandomIntUpto(int max) 266 { 267 return nextInt(max); 268 } 269 270 /** 271 * @return random int between min and max, e.g params of [5,7] returns 5,6 or 7 272 */ generateRandomIntBetween(int min, int max)273 public static int generateRandomIntBetween(int min, int max) 274 { 275 return min +generateRandomIntUpto(max + 1 - min); 276 } 277 } 278