I am writing some kotlin, and would like to use the Prime constructor for BigIntegers. Because I want to generate some really big prime numbers.
The documentation for the constructor looks like this:
BigInteger(int bitLength, int certainty, Random rnd)
Constructs a randomly generated positive BigInteger that is probably prime, with the specified bitLength.
My problem is here that I find it a little unspecified what these arguments actually do.
bitlength
My first assumption is that this is just the amount of bits that I want the BigInt to have. This seems simple enough, but still i'm a bit in doubt about whether this means my number will use this many bits, or if it is a maximum, minimum etc.
certainty
This one is really mystical to me. Is this the probability that the number is prime, or the probability of that is has the beforementioned bitlength.
And on top of that, which unit do we use to denote certainty? percentages, is some probability ranking system i have never heard of?
** rnd**
I assume this is just a random generator as they come standardly in java.
But what is it used for in this context? it would be nice to be able to know why I should provide one
Hope someone can help in clearing my my confusion
The rest of the documentation is here:
https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
Related
Let's assume I have a reliably truly random source of random numbers, but it is very slow. It only give me a few hundreds of numbers every couple of hours.
Since I need way more than that I was thinking to use those few precious TRN I can get as seeds for java.util.Random (or scala.util.Random). I also always will pick a new one to generate the next random number.
So I guess my questions are:
Can the numbers I generate from those Random instance in Java be considered truly random since the seed is truly random?
Is there still a condition that is not met for true randomness?
If I keep on adding levels at what point will randomness be lost?
Or (as I thought when I came up with it) is truly random as long as the stream of seeds is?
I am assuming that nobody has intercepted the stream of seeds, but I do not plan to use those numbers for security purposes.
For a pseudo random generator like java.util.Random, the next generated number in the sequence becomes predictable given only a few numbers from the sequence, so you will loose your "true randomness" very fast. Better use one of the generators provided by java.security.SecureRandom - these are all strong random generators with an VERY long sequence length, which should be pretty hard to be predicted.
Our java Random gives uniformly spread random numbers. That is not true randomness, which may yield five times the same number.
Furthermore for every specific seed the same sequence is generated (intentionally). With 2^64 seeds in general irrelevant. (Note hackers could store the first ten numbers of every sequence; thereby rapidly catching up.)
So if you at large intervals use a truely random number as seed, you will get a uniform distribution during that interval. In effect not very different from not using the true randomizers.
Now combining random sequences might reduce the randomness. Maybe translating the true random number to bytes, and xor-ing every new random number with another byte, might give a wilder variance.
Please do not take my word only - I cannot guarantee the mathematical correctness of the above. A math/algorithmic forum might give more info.
When you take out more bits, than you have put in they are for sure no longer truly random. The break point may even occur earlier if the random number generator is bad. This can be seen by considering the entropy of the sequences. The seed value determines the sequence completely, so there are at most as many sequences as seed values. If they are all distinct, the entropy is the same as that of the seeds (which is essentially the number of seed bits, assuming the seed is truly random).
However, if different seeds lead to the same pseudo random sequence the entropy of the sequences will be lower than that of the seeds. If we cut off the sequences after n bits, the entropy may be even lower.
But why care if you don't use it for security purposes? Are you sure the pseudo random numbers are not good enough for your application?
there is some ways to generate random Numbers in java
one of them is this:
Random rand=new Random();
int randomInteger=rand.nextInt();
now my question is this: can we predict next random Number?
edited after 4 answers:
my real problem is this:
I'm working on a Snake Game( nibbles in Linux) and I'm programing the snake to move, now I want to know if it's possible to Predict the next place that the apple will appear.
is it possible?
You can not only predict it, but know it absolutely, if you know exactly what System.currentTimeMillis would return when you called new Random(). That's because new Random() is a shortcut for new Random(System.currentTimeMillis()), which sets the seed of a pseudo-random generator. (Well, that's what it did when I last looked at the source; the docs don't actually say it has to use that.) if you know the seed that new Random() used. Pseudo-random generators are deterministic, if you know the seed, you know the sequence. Update: Looking at the Java 6 source [I don't have Java 7 source handy], the default seed is a combination of a seed number that gets incremented on use, plus System.nanoTime. So you'd need to know both of those. Raises the bar.
If you don't know the exact value of System.currentTimeMillis() as of when new Random() occurs the seed used by new Random(), then it's very difficult indeed to predict what the next value will be. That's the point of pseudo-random generators. I won't say it's impossible. Just really, really hard to do with any degree of confidence.
Update after question edit: It's possible, but very, very hard, and in terms of doing so in a way that would allow a player to improve their score in the game, I'd say you can ignore it.
The "random" numbers generated by the Random class are generated algorithmically, and as such are really pseudo-random numbers. So yes, in theory, you can predict the next number. Knowing one number that Random has produced, though, or even a series of numbers, isn't enough information to predict the next number; you would also need to know the seed that the Random object is using, and you would need to follow its pseudo-random number generation algorithm.
If you would like a repeatable set of "random" numbers, you can specify your own seed when creating an instance of Random, e.g.
Random rand = new Random(1234); // Replace 1234 with any value you'd like
Every time you instantiate Random with the same seed, you'll get the same series of numbers. So, for example, you could write a small command-line program that instantiates Random with some seed and prints a list of the numbers it returns, and then instantiate Random with the same seed in your code. Then you would know which numbers your code will receive and in what order. That's very handy for debugging.
There could be NO really random numbers on deterministic devices like computer. But.
If you want a cryptographically secure random number, use SecureRandom: http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html
Random uses a deterministic algorithm:
If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers.
http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#Random
Essentially, if you know the seed of the random number generator, you can predict the entire sequence with certainty. If you don't, no matter how many numbers you generate, there's no way to accurately predict the next one.
Note that if you're relying on the numbers being unpredictable for security, you should be using java.secure.SecureRandom rather than java.util.Random.
As others answer this question, it is possible to predict randomness of java.util.Random if you know the starting seed.
If you are working on a linux like system, take a look at these special files /dev/random and dev/urandom. Reads from these files are said to return "better" random numbers, the randomness depends on keyboard activity, mouse movement and some other exotic factors.
See this Wikipedia page for details. This page also says equivalent APIs exist in Windows.
I am new to Java and one of my class assignments is to find a prime number at least 100 digits long that contains the numbers 273042282802155991.
I have this so far but when I compile it and run it it seems to be in a continuous loop.
I'm not sure if I've done something wrong.
public static void main(String[] args) {
BigInteger y = BigInteger.valueOf(304877713615599127L);
System.out.println(RandomPrime(y));
}
public static BigInteger RandomPrime(BigInteger x)
{
BigInteger i;
for (i = BigInteger.valueOf(2); i.compareTo(x)<0; i.add(i)) {
if ((x.remainder(i).equals(BigInteger.ZERO))) {
x.divide(i).equals(x);
i.subtract(i);
}
}
return i;
}
Since this is homework ...
There is a method on BigInteger that tests for primality. This is much much faster than attempting to factorize a number. (If you take an approach that involves attempting to factorize 100 digit numbers you will fail. Factorization is believed to be an NP-complete problem. Certainly, there is no known polynomial time solution.)
The question is asking for a prime number that contains a given sequence of digits when it is represented as a sequence of decimal digits.
The approach of generating "random" primes and then testing if they contain those digits is infeasible. (Some simple high-school maths tells you that the probability that a randomly generated 100 digit number contains a given 18 digit sequence is ... 82 / 1018. And you haven't tested for primality yet ...
But there's another way to do it ... think about it!
Only start writing code once you've figured out in your head how your algorithm will work, and done the mental estimates to confirm that it will give an answer in a reasonable length of time.
When I say infeasible, I mean infeasible for you. Given a large enough number of computers, enough time and some high-powered mathematics, it may be possible to do some of these things. Thus, technically they may be computationally feasible. But they are not feasible as a homework exercise. I'm sure that the point of this exercise is to get you to think about how to do this the smart way ...
One tip is that these statements do nothing:
x.divide(i).equals(x);
i.subtract(i);
Same with part of your for loop:
i.add(i)
They don't modify the instances themselves, but return new values - values that you're failing to check and do anything with. BigIntegers are "immutable". They can't be changed - but they can be operated upon and return new values.
If you actually wanted to do something like this, you would have to do:
i = i.add(i);
Also, why would you subtract i from i? Wouldn't you always expect this to be 0?
You need to implement/use miller-rabin algorithm
Handbook of Applied Cryptography
chapter 4.24
http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf
While conducting some experiments in Java, my project supervisor reminded me to seed each iteration of the experiment with a different number. He also mentioned that I should use prime numbers for the seed values. This got me thinking — why primes? Why not any other number as the seed? Also, why must the prime number be sufficiently big? Any ideas? I would've asked him this myself, but its 4am here right now, everyone's asleep, I just remembered this question and I'm burning to know the answer (I'm sure you know the feeling).
It would be nice if you could provide some references, I'm very interested in the math/concept behind all this!
EDIT:
I'm using java.util.Random.
FURTHER EDIT:
My professor comes from a C background, but I'm using Java. Don't know if that helps. It appears that using primes is his idiosyncrasy, but I think we've unearthed some interesting answers about generating random numbers. Thanks to everyone for the effort!
Well one blink at the implementation would show you that he CAN'T have any reason for that claim at all. Why? Because that's how the set seed function looks like:
synchronized public void setSeed(long seed) {
seed = (seed ^ multiplier) & mask;
this.seed.set(seed);
haveNextNextGaussian = false;
}
And that's exactly what's called from the constructor. So even if you give it a prime, it won't use it anyhow, so if at all you'd have to use a seed s where (s^ multiplier) & mask results in a prime ;)
Java uses a usual linear congruency method, i.e.:
x_n+1 = (a * x_n + c) mod m with 2 <= a < m; 0 <= c < m.
Since you want to get a maximal periode, c and m have to be relatively prime and a few other quite obscure limitations, plus a few tips how to get a practically useful version. Knuth obviously covers that in detail in part2 ;)
But anyhow, the seed doesn't influence the qualities of the generator at all. Even if the implementation would be using a Lehmer generator, it would obviously make sure that N is prime (otherwise the algorithm is practically useless; and not uniformly distributed if all random values would have to be coprime to a non prime N I wager) which makes the point moot
If the generator is a Lehmer generator, than the seed and the modulus must be co-prime; see the wiki page. One way to ensure they are co-prime is to start with a prime number.
If you are talking about java.util.Random, or one of its subclasses in the Oracle runtime, there's no reason for this. It's just a whim of your supervisor.
I understand that multiplication by a large number before xoring should help with badly distributed operands but why should the multiplier be a prime?
Related:
Why should hash functions use a prime number modulus?
Close, but not quite a Duplicate:
Why does Java’s hashCode() in String use 31 as a multiplier?
There's a good article on the Computing Life blog that discusses this topic in detail. It was originally posted as a response to the Java hashCode() question I linked to in the question. According to the article:
Primes are unique numbers. They are unique in that, the product of a prime with any other number has the best chance of being unique (not as unique as the prime itself of-course) due to the fact that a prime is used to compose it. This property is used in hashing functions.
Given a string “Samuel”, you can generate a unique hash by multiply each of the constituent digits or letters with a prime number and adding them up. This is why primes are used.
However using primes is an old technique. The key here to understand that as long as you can generate a sufficiently unique key you can move to other hashing techniques too. Go here for more on this topic about hashes without primes.
Multiplying by a non-prime has a cyclic repeating pattern much smaller than the number. If you use a prime then the cyclic repeating pattern is guaranteeed to be at least as large as the prime number.
I'm not sure exactly which algorithm you're talking about, but typically the constants in such algorithms need to be relatively prime. Otherwise, you get cycles and not all the possible values show up in the result.
The number probably doesn't need to be prime in your case, only relatively prime to some other numbers, but making it prime guarantees that. It also covers the cases where the other magic numbers change.
For example, if you are talking about taking the last bits of some number, then the multiplier needs to not be a multiple of 2. So, 9 would work even though it's not prime.
Consider the simplest multiplication: x2.
It is equivalent to a left-bitshift. In other words, it really didn't "randomize" the data, it just shifted it over.
Same with x4, or any power of two. The original data is intact, just shifted.
Now, multiplication by other numbers (non-powers of two) are not as obvious, but still have the same problem, more or less. The original data is intact, or trivially transformed. (eg. x5 is the same as left-bitshift two places, then add on the original data).
The point of GetHashCode is to essentially distribute the data as randomly as possible. Multiplying by a prime number guarantees that the answer won't be a simpler transform like bit-shifting or adding a number to itself.