001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.util; 019 020import javax.annotation.concurrent.ThreadSafe; 021 022/** 023 * A fast random class which generates low-quality pseudo-random values 024 * 025 * <p>Normally such a class should have been implemented upon using the time system with currentTimeMills(), however 026 * this was avoided for two reasons: 027 * <ul> 028 * <li>Security - If the timer did not update in time, a malicious user may use that same random. While this is not 029 * designed as a cryptographically secure random, malice is a strong enough reason to use nanoTime()</li> 030 * <li>Randomness - Using successive calls to this random may produce the same random number. The occurrance of this 031 * depends on the overhead of the method call, in which case a full millisecond has not passed yet, rather than the 032 * possibility that the timer has not updated (which again, is another plausible reason for this)</li> 033 * </ul></p> 034 * 035 * <p>Note that the methods which produce a random using the hash is not a seed. The next number is never ever 036 * consistent unless nanoTime returns the same value and the hashed object is the same. The methods which do not 037 * provide 038 * a hash do not create a new object, rather it does not hash the nanoTime at all.</p> 039 * 040 * @author The TridentSDK Team 041 * @since 0.3-alpha-DP 042 */ 043@ThreadSafe 044public final class FastRandom { 045 private FastRandom() { 046 } 047 048 /** 049 * Finds a random number 050 * 051 * @return the random number 052 */ 053 public static long random() { 054 long x = System.nanoTime(); 055 x ^= (x << 21); 056 x ^= (x >>> 35); 057 x ^= (x << 4); 058 return (x > 0) ? x : -x; 059 } 060 061 /** 062 * Finds a random number with an upper limit 063 * 064 * @param upper the returned value is < upper 065 * @return the random number 066 */ 067 public static long random(int upper) { 068 long x = System.nanoTime(); 069 x ^= (x << 21); 070 x ^= (x >>> 35); 071 x ^= (x << 4); 072 073 long rand = x & (upper - 1); 074 return (rand > 0) ? rand : -rand; 075 } 076 077 /** 078 * Finds a random number with a hash 079 * 080 * @param hash the object to randomize the hash with hashCode 081 * @return the random number 082 */ 083 public static long random(Object hash) { 084 long x = System.nanoTime() ^ hash.hashCode(); 085 x ^= (x << 21); 086 x ^= (x >>> 35); 087 x ^= (x << 4); 088 return (x > 0) ? x : -x; 089 } 090 091 /** 092 * Finds a random number with a hash 093 * 094 * @param upper the returned value is < upper 095 * @param hash the object to randomize the seed with hashCode 096 * @return the random number 097 */ 098 public static long random(int upper, Object hash) { 099 long x = System.nanoTime() ^ hash.hashCode(); 100 x ^= (x << 21); 101 x ^= (x >>> 35); 102 x ^= (x << 4); 103 104 long rand = x & (upper - 1); 105 return (rand > 0) ? rand : -rand; 106 } 107}