I am trying to generate two 9 digit long random long value in Java using the below code:
for (int i =0;i<2;i++) {
String axisIdStr = Long.toString((long)(System.nanoTime() * (Math.random() * 1000)));
System.out.println("######## axisIdStr "+axisIdStr);
String axId = axisIdStr.substring((axisIdStr.length() -9), axisIdStr.length()) ;
}
But when I run this in windows, i get two different numbers where as when run in mac, I get same two numbers. Why is this happening ?
Can you suggest a better way to generate the long values?
According to your requirement you need to generate 9 digit random numbers. As in the comment suggested you can do it using random.Below I have just given one solution to generate random number between two numbers.
long lowerLimit = 123456712L;
long upperLimit = 234567892L;
Random r = new Random();
long number = lowerLimit+((long)(r.nextDouble()*(upperLimit-lowerLimit)));
You could create an array a[] of int of size 9, and populate with random integers 0-9. Then sum the array up multiplying accordingly.
a[8]*1 + a[7]*10 + a[6]*100 ...
You need to make sure that a[0] only takes digits 1-9 tho...
To get even more random sequence, you Ideally should work on Strings, then you would be able to get 0 on the start position of your random "string", it won't be a number.
Or maybe generate somthing pseudo random and strip last 9 digits out of it.
That's the DIY version of what you could accomplish with what's already out there...
Regards
Related
This question already has answers here:
How to generate a random BigInteger value in Java?
(8 answers)
Closed 2 years ago.
I am attempting to generate a random 20 digit BigInteger in Java.
So far, I have been able to generate a fixed length hex value.
// generate a user-specified number of random bytes
public void getRandomNumber(int count) {
byte[] bytes = new byte[count];
new SecureRandom().nextBytes(bytes);
String random = new String(Hex.encode(bytes));
System.out.println(random);
}
This is ideal for a fixed length hex generation. But I struggle to find an efficient method of doing this for a decimal representation; when converting from hex to BigInteger(hexValue, 16), the length will vary.
I have considered trying this by setting upper and lower bounds, or by generating something big enough and trimming to the desired length, but those methods do not feel very clean.
Edit: The solution I have came up with that is working fine in my program:
// generate a random number with specified bit length
public void getTokenID() {
int count = 64;
SecureRandom rnd = new SecureRandom();
BigInteger randomCountLength;
String token;
do {
randomCountLength = new BigInteger(count, rnd);
token = randomCountLength.toString();
} while (token.length() != 20);
Tid = token;
}
What I understand that your problem is to generate random number with fixed length (fixed number of digits)
It is obvious that using hex value will work since any hex digit represent 4 bytes. So when you fix the length of bytes (bytes table in your code) it work fine
What I advice you when dealing with decimal number is :
1- There is methods for generating random number with lower and upper bound, for example Random betwen 5 and 10, so if you want for example a random number with 20 digits , you have to generate random number between (10^19) and (10^20-1)
2- The second is hardcoded method to make a loop of 20 iterations when you generate random digit (between 0 and 9 exept the the digit of strong weight which must be between 1 and 9) and you get the number.
I want to create a randomly generated 16 digit-number in java.But there is a catch I need the first two digits to be "52". For example, 5289-7894-2435-1967.
I was thinking of using a random generator and create a 14 digit number and then add an integer 5200 0000 0000 0000.
I tried looking for similar problems and can't really find something useful. I'm not familiar with the math method,maybe it could solve the problem for me.
First, you need to generate a random 14-digit number, like you've done:
long first14 = (long) (Math.random() * 100000000000000L);
Then you add the 52 at the beginning.
long number = 5200000000000000L + first14;
One other way that would work equally well, and will save memory, since Math.random() creates an internal Random object:
//Declare this before you need to use it
java.util.Random rng = new java.util.Random(); //Provide a seed if you want the same ones every time
...
//Then, when you need a number:
long first14 = (rng.nextLong() % 100000000000000L) + 5200000000000000L;
//Or, to mimic the Math.random() option
long first14 = (rng.nextDouble() * 100000000000000L) + 5200000000000000L;
Note that nextLong() % n will not provide a perfectly random distribution, unlike Math.random(). However, if you're just generating test data and it doesn't have to be cryptographically secure, it works as well. It's up to you which one to use.
Random rand = new Random();
String yourValue = String.format((Locale)null, //don't want any thousand separators
"52%02d-%04d-%04d-%04d",
rand.nextInt(100),
rand.nextInt(10000),
rand.nextInt(10000),
rand.nextInt(10000));
You can generate 14 random digits and then append at the beginning "52". E.g.
public class Tes {
public static void main(String[] args) {
System.out.println(generateRandom(52));
}
public static long generateRandom(int prefix) {
Random rand = new Random();
long x = (long)(rand.nextDouble()*100000000000000L);
String s = String.valueOf(prefix) + String.format("%014d", x);
return Long.valueOf(s);
}
}
Create a 14 random digit number. with Math.random
Concatenate to it at the begining the "52" String.
Convert the string with Integer.parseInt(String) method
This question already has answers here:
Returning a random even number
(5 answers)
Closed 9 years ago.
How do you generate random numbers that go up by twos using Math.random()? For example, I'm trying to generate a random number from the set (2,4,6,8), how would you go it?
For this specific set you could use
(int)(Math.random() * 4) * 2 + 2
Here:
Math.random() generates a number that's greater or equal to 0.0 and strictly less than 1.0;
(int)(... * 4) gives one of 0, 1, 2, 3.
... * 2 + 2 gives one of 2, 4, 6, 8.
Okay, let's make a real general solution.
int lower = 2;
int upper = 8;
int step = 2;
int rand = (int)(Math.random() * (upper-lower+1));
int result = rand - rand%step + lower;
If you want to generate numbers within another set than the one you specified, just change the lower, upper and step variables to fit your set. It includes the upper bound if it's in the set.
The (almost) completely general approach isn't that hard.
static randInt(int first, int last, int step) {
int nsteps = (last+1-first) / step;
return first + step*(int)(nsteps*Math.random());
}
That returns a random integer from {start, start+step, start+2*step, ... } up to and including stop, or the last number before stop if stop is not part of the sequence.
int choice = randInt(2, 8, 2); /* random choice from {2, 4, 6, 8} */
...solved the sample question.
The (almost) part is that this doesn't handle integer overflow or sign errors in the arguments (step is zero, step<0 when first<last, or vice versa.)
int[] numSet={2,4,6,8};
Random myRand=new Random();
int myNum=numSet[myRand.nextInt(numSet.length)];
This creates an array of numbers, the random object, then picks a random element from the array of numbers. This does not assume that the numbers are in any sort of mathematical series. They could be 11, 25, 31, 876, 984368, 7432, 84562, for that matter.
Please don't tell me that there's a polynomial that generates that set from its y-values. I know.
Put those numbers in an array.
Generate a random number using the length of the array - 1 and use it as the index to randomly choose an array element.
You can also use the java.util.Random class like this:
int values[] = {2,4,6,8};
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(values.length);
int randomValue = values[randomInt]; /* Here's your random value from your set */
I would like to add a more general answer.
Assume the smallest integer in the set is A and the size of the set is S. A random integer from the set would be like this:
A + myRandom.nextInt(S) * 2
For your specific example in Java, it would be:
Random myRandom = new Random();
int randomNum = 2 + myRandom.nextInt(4) * 2;
I have an app I am writing for iOS and Android. On startup I am trying to get a random number between 1 and 6.
iOS (Objective-C):
int random = rand() % (6 - 1) + 1;
Android (Java):
Random random = new Random();
int num = random.nextInt(6)+1;
In both cases they return 3 every time.
From other questions I have read, people are having the same issue because they are looping through randoms and keep reinstantiating the Random object. But I just want one random number, so I am only instantiating it once.
So, how can I get either of these pieces of code to get a number 1-6 instead of just 3?
For the Objective-C part, I can tell you that you have to seed the random, like this:
srand(time(0)); // seed it using the current time
And for the Java part, the new Random() constructor automatically seeds it in the default JVM for desktop applications, but not on Android. On Android, it uses a default seed value.
Random rand = new Random(System.nanoTime());
In Objective-C, you could alternately use the recommended arc4random() function that does not need to be seeded. You would use it like this:
int random = (arc4random() % 5) + 1;
A huge benefit of this function over rand() is that is has twice the range of rand(), thus allowing for "more random" numbers.
The best solution is to use arc4random_uniform if possible, it is available in iOS 4.3 and above. It eliminates bias that is usually introduced by the mod operator.
+ (u_int32_t)randomInRangeLo:(u_int32_t)loBound toHi:(u_int32_t)hiBound {
int32_t range = hiBound - loBound + 1;
return loBound + arc4random_uniform(range);
}
Note that no seeding is necessary and it produces cryptographic quality random numbers.
Not sure about Random on Android, but in other cases, you probably want to seed the Random instance with something reasonably unique, like the system time.
Random r = new Random(System.currentTimeMillis());
I tried the Java part and it works OK for me, but you can try to instantiate Random using time as a seed:
java.util.Date d = new java.util.Date();
Random random = new Random(d.getTime());
int num = random.nextInt(6)+1;
System.out.println(num);
I want to generate a random number of 14 positive digits only and I use the below function for it:
public void random()
{
Random number = new Random();
long l = number.nextLong();
number.setSeed(System.currentTimeMillis());
long num = Math.abs(number.nextInt())%999 + (l/100000); // problematic line
mTextBox.setString("" + num);
}
I very new to to JavaMe, I have made above function myself but I believe it is not working as expected. It also generates -ve numbers. Also sometimes one or two digits are missing in generated number resulting in 12 or 13 numbers not 14.
Any suggestions or improvement to the code will be highly appreciated.
If you want 14 digits, then you should use 14 calls to number.nextInt(10) - something like this:
public static String randomDigits(Random random, int length)
{
char[] digits = new char[length];
// Make sure the leading digit isn't 0.
digits[0] = (char)('1' + random.nextInt(9);
for (int i = 1; i < length; i++)
{
digits[i] = (char)('0' + random.nextInt(10));
}
return new String(digits);
}
Note that I've made the instance of Random something you pass in, rather than created by the method - this makes it easier to use one instance and avoid duplicate seeding. It's also more general purpose, as it separates the "use the string in the UI" aspect from the "generate a random string of digits".
I don't know whether Random.nextInt(int) is supported on J2ME - let me know if it's not. Using Math.abs(number.nextInt())%999 is a bad idea in terms of random distributions.
I didn't understand what you really want, the code suggests that you want a 3 digit number (%999).
Otherwise you can create a 14 digit number between 1000000000000000 and 9999999999999999 by
long num = 1000000000000000L + (long)(number.nextDouble() * 8999999999999999.0);
note (1 / 100000) is 0 (zero) since it is done by integer division, use (1.0 / 100000.0) for double division
long num = 10000000000000L+(long)(random.nextDouble()*90000000000000.0);
EDIT:
mTextBox.setString(MessageFormat.format("{0,number,00000000000000}",
new Object[] {new Long(num)}));
You are getting negative numbers because Random.nextInt() returns any 32-bit integer, and half of them are negative. If you want to get only positive numbers, you should use the expression Random.nextInt() & 0x7fffffff or simply Random.nextInt(10) for a digit.