|
Random Stupidity
Last post 03-12-2008 6:06 AM by RayS. 37 replies.
-
02-23-2008 1:13 PM
|
|
-
snoofle


- Joined on 06-22-2006
- Posts 523
|
I found this deep in the bowels of something written by our offshore counterparts, in it's entirety:
/**
* We all know that random number generators aren't truly random.
* This class generates random numbers a bit more randomly.
*/
public final class Randomizer {
// OP Note: not sure why matching square brackets ont' show up in post...
private static final char [ digits = { '0','1','2','3','4','5','6','7','8','9' };
// Allow this to be instantiated in parallel in multiple threads
public Randomizer() {
}
public final double random() {
final StringBuilder sb = new StringBuilder();
sb.append(getRandomDigitString());
sb.append(".");
sb.append(getRandomDigitString());
return Double.parseDouble(sb.toString());
}
private String getRandomDigitString() {
final StringBuilder sb = new StringBuilder();
int n = getRandomNumberOfDigits();
for (int i=0; i<n; i++) {
sb.append(getRandomDigit());
}
if (n==0) {
sb.append("0");
}
return sb.toString();
}
private char getRandomDigit() {
return digits[(int)(Math.random() * 10)];
}
private int getRandomNumberOfDigits() {
return (int) ((Math.random() * 100) * Math.random());
}
}
Beware the purple duck!
|
|
-
-
Jonathan Holland


- Joined on 01-10-2008
- Posts 163
|
Ah, India.... Reinventing methods poorly since 1999. I like how it doesn't even get a seed.
|
|
-
-
PeriSoft


- Joined on 08-17-2007
- Posts 70
|
You know, I remember discovering QuickBASIC's pseudo-randomness when I was 10 or 11, and even then I didn't think that pseudo-randomizing a pseudo-random random would be randomer. I could see this providing a somewhat longer *visible* cycle time between obvious repetitions with a really, really crappy generator, but... yeah. WTF indeed. If you really need a true random, just find a modern 200+gb hard drive more than a year old and try to read from a file...
|
|
-
-
lidden


- Joined on 02-06-2008
- Posts 2
|
PeriSoft:I could see this providing a somewhat longer *visible* cycle time between obvious repetitions with a really, really crappy generator, but... yeah. WTF indeed. Well getRandomNumberOfDigits is more likely to give a small number then a larger so the code is horribly broken. I'm not sure fixing that would make the class a fair randomness generator.
|
|
-
-
-
Otterdam


- Joined on 09-25-2006
- Posts 110
|
Jonathan Holland:Ah, India.... Reinventing methods poorly since 1999. I like how it doesn't even get a seed. Hey, it's their fault. They should've asked for good codes.
|
|
-
-
-
PSWorx


- Joined on 04-28-2006
- Posts 682
|
// Allow this to be instantiated in parallel in multiple threads
On the risk of introducing even more stupidity, this brings up something I've wondered for some time already: Couldn't you create a pretty good "true" random number generator using a kind of "controlled race condition"? Imagine something like this:
// Thread 1: forever { number++; // adjust actual formulas for uniform distribution sleep(1); } // Thread 2: forever { number--; sleep(1); } // Thread 3: int getRandomNumber() { return number; } Of course this is still technically deterministic, but would actually depend on so many different variables - many of them changing over time even - that it didn't matter. Or would it? Where is the flaw?
|
|
-
-
Otac0n


- Joined on 05-18-2005
- Wichita, KS
- Posts 77
|
PSWorx:// Allow this to be instantiated in parallel in multiple threads
On the risk of introducing even more stupidity, this brings up something I've wondered for some time already: Couldn't you create a pretty good "true" random number generator using a kind of "controlled race condition"? Imagine something like this:
// Thread 1: forever { number++; // adjust actual formulas for uniform distribution sleep(1); } // Thread 2: forever { number--; sleep(1); } // Thread 3: int getRandomNumber() { return number; } Of course this is still technically deterministic, but would actually depend on so many different variables - many of them changing over time even - that it didn't matter. Or would it? Where is the flaw? Well, this would almost always return the same number. Better would be taking a cryptographically secure hash of a pseudo random number and the system time.
The "Non Compos Mentis" Programmer
|
|
-
-
Nether


- Joined on 06-02-2007
- Posts 56
|
PSWorx:// Allow this to be instantiated in parallel in multiple threads
On the risk of introducing even more stupidity, this brings up something I've wondered for some time already: Couldn't you create a pretty good "true" random number generator using a kind of "controlled race condition"? Imagine something like this:
// Thread 1: forever { number++; // adjust actual formulas for uniform distribution sleep(1); } // Thread 2: forever { number--; sleep(1); } // Thread 3: int getRandomNumber() { return number; } Of course this is still technically deterministic, but would actually depend on so many different variables - many of them changing over time even - that it didn't matter. Or would it? Where is the flaw? So thread 3 returns the number of times A has been scheduled since T minus the number of times B has been scheduled since T? It really would not be very random, and certainly not uniform, since it is extremely biased to 0 on both sides of the number line. It would also depend on the process scheduling algorithm which could vary widely between operating systems, even different versions of the same operating system. I think if you wanted to use the system environment as the input to your RNG there are better properties to use. And I'm not sure what a "crypto-graphically secure" number really has to do with anything. The way standard RNGs work currently, as I understand it, is that they present very, very long series of numbers, indexed by the seed you supply. The values in the series are not significantly correlated to the value of the seed, and the values of numbers in the same series are not significantly correlated to each other. Most libraries do an excellent job of this, and given those properties, you only need ONE value that will not likely have the exact same value every time it is needed. The system time is an excellent candidate. There's no need to take numbers from multiple sources and marry them with any kind of convoluted mathematical strategy.
|
|
-
-
vrykoul


- Joined on 06-19-2007
- Posts 1
|
public int random() {
return 5; //chosen by a fair roll of the dice }
|
|
-
-
-
KNY


- Joined on 07-19-2006
- Posts 25
|
vrykoul:public int random() {
return 5; //chosen by a fair roll of the dice }
If you're going to steal a joke, at least do it properly.
|
|
-
-
mendel


- Joined on 01-17-2008
- Posts 31
|
PSWorx:On the risk of introducing even more stupidity, this brings up something I've wondered for some time already: Couldn't you create a pretty good "true" random number generator using a kind of "controlled race condition"? Hey, stupidity is fun! Use the FM synth on the soundcard (if you can) to output white noise, sample that, use the least significant bits of that. That is provided the white noise is created by an analog circuit and not simulated by a RNG digitally or looping the same white noise sample over and over... Of course, if you want quantum theory proof randomness delivered via Internet, there is nothing better than John Walker's hotbits at http://www.fourmilab.ch/hotbits/ .
|
|
-
-
DaveK


- Joined on 02-22-2006
- Posts 398
|
KNY: vrykoul:public int random() {
return 5; //chosen by a fair roll of the dice }
If you're going to steal a joke, at least do it properly. And if you can't do that, at least make it a bizarre juxtaposition of in-references:
public int random() {
return 9; // that's the problem with randomness: you can never be sure.
}
|
|
-
-
Aaron


- Joined on 07-10-2007
- Posts 177
|
PSWorx:On the risk of introducing even more stupidity, this brings up something I've wondered for some time already: Couldn't you create a pretty good "true" random number generator using a kind of "controlled race condition"? Aside from the fact that this doesn't work, you're falling into the classic programmer trap of worrying about a specific solution instead of the general problem. Why do you need a "true" RNG? - For encryption? Any decent crypto library can give you cryptographically secure randomness. - For statistical simulations? No need, the pseudo-random sequences will give the same distribution as "true" randomness, that's the whole point. - For fudge-factoring? Using the system time as your random seed is fine for this. I won't even get into the debate about "true" randomness being merely the result of complex chaos systems - suffice it to say that the question is not *is it* random, but *how* random is it. If it's not possible for an outside observer to predict the next number in the sequence simply by studying the past numbers, then it's random enough for just about any practical purpose. Of course the "threads" version doesn't fit this criteria at all - it uses some more-or-less random factors in a way that will produce a highly predictable and uniform distribution around the mean of zero. Plot millions points from even the most highly uncorrelated data and you'll always end up with a Gaussian distribution. That's why you're only supposed to randomize once - keep doing it and you'll actually end up with data that's more correlated than what you started with.
|
|
-
-
mendel


- Joined on 01-17-2008
- Posts 31
|
Sorry to revive this thread, but here's a nice WTF: Aaron:Why do you need a "true" RNG? - For encryption? Any decent crypto library can give you cryptographically secure randomness. - For statistical simulations? No need, the pseudo-random sequences will give the same distribution as "true" randomness, that's the whole point. - For fudge-factoring? Using the system time as your random seed is fine for this. Have you spotted the WTF? Using the system time as random seed means that if you know the day the random generator was run and the system time is accurate to 1/100 of a second, an attacker only has to try at most 8 million possibilities before he finds the correct sequence. For security, this is worse than a 4-letter password.
|
|
-
-
-
MarcB


- Joined on 10-24-2006
- Posts 511
|
mendel:an attacker only has to try at most 8 million possibilities before he finds the correct sequence. For security, this is worse than a 4-letter password. bzzt... 4 letter password loses, by ever so slight a margin, assuming you're allowing mixed case. 26**4 = 456,976. 52**4 = 7,311,616. Close, but still not as good as 1:8,000,000
-- Never play leapfrog with a unicorn
|
|
-
-
MarcB


- Joined on 10-24-2006
- Posts 511
|
mendel:Have you spotted the WTF? That's why it's listed as a "fudge-factor" in the choices. If you're dealing with a system/process where there is "an attacker", malicious or not, then you use the crypto library option as the only possible choice. mendel:an attacker only has to try at most 8 million possibilities before he finds the correct sequence. For security, this is worse than a 4-letter password. bzzt. 4-letter password loses, by ever so slight a margin, if you're allowing mixed-case passwords. 52**4 = 7,311,616. Close, but not quite 1:8,000,000
-- Never play leapfrog with a unicorn
|
|
-
-
Outlaw Programmer


- Joined on 01-07-2008
- Posts 73
|
// Allow this to be instantiated in parallel in multiple threads public Randomizer() { }
WTF does that comment even mean? What does a constructor have to do with multiple threads? Especially since the only thing this class uses is a static field and local variables. At least the class was declared as final. That makes it extra secure!
-- The sacrifice the code demanded... --
|
|
-
-
mendel


- Joined on 01-17-2008
- Posts 31
|
MarcB:That's why it's listed as a "fudge-factor" in the choices. If you're dealing with a system/process where there is "an attacker", malicious or not, then you use the crypto library option as the only possible choice. I had mentioned Hot Bits earlier. Where does the crypto library get its seed from? MarcB: mendel:an attacker only has to try at most 8 million possibilities before he finds the correct sequence. For security, this is worse than a 4-letter password.
bzzt. 4-letter password loses, by ever so slight a margin, if you're allowing mixed-case passwords. 52**4 = 7,311,616. Close, but not quite 1:8,000,000 I was allowing numbers as well, and some symbols people like to use (maybe - and .) for an even 64, which nets me 16M. It's a seat-of-pants estimate anyway (as if being less secure than a 5-letter password was better....), given that often you can determine the system time closer than that and that I don't really know how long a clock tick is. For your continued entertainment, one could derive a random seed from the Time Stamp Counter. (Virtualdub.org : "The time stamp counter is a 64-bit counter that was added to most
x86 CPUs starting around the Pentium era, and which counts up at the
clock rate of the CPU. The TSC is generally readable via the RDTSC
instruction from user mode, making it the fastest, easiest, and most
precise time base available on modern machine.") Assuming that the TSC counts at 2 GHz and also assuming that many users start the program within 20 minutes of booting their computer, we're getting 7-letter-password security here (41 bit or thereabouts). If you do this on a server, it's uptime becomes a security-critical piece of data....
|
|
-
-
Pidgeot


- Joined on 09-19-2007
- Posts 60
|
mendel:
For your continued entertainment, one could derive a random seed from the Time Stamp Counter. (Virtualdub.org : "The time stamp counter is a 64-bit counter that was added to most x86 CPUs starting around the Pentium era, and which counts up at the clock rate of the CPU. The TSC is generally readable via the RDTSC instruction from user mode, making it the fastest, easiest, and most precise time base available on modern machine.") Assuming that the TSC counts at 2 GHz and also assuming that many users start the program within 20 minutes of booting their computer, we're getting 7-letter-password security here (41 bit or thereabouts).
If you do this on a server, it's uptime becomes a security-critical piece of data....
Well, not necessarily. Certain multi-core CPUs will keep that value in sync, but others won't. I don't think Intel has had this issue, but AMD has, which has caused a lot of slightly older games to require being locked to a specific core.
That, as it happens, is also why using that value for timing purposes is discouraged these days.
|
|
-
-
pscs


- Joined on 10-30-2007
- Posts 40
|
mendel:Have you spotted the WTF? Using the system time as random seed means that if you know the day the random generator was run and the system time is accurate to 1/100 of a second, an attacker only has to try at most 8 million possibilities before he finds the correct sequence. For security, this is worse than a 4-letter password.
That's why he said you'd only use that for something that didn't have to be secure. Please read what he said.
|
|
-
-
RayS


- Joined on 01-22-2005
- Posts 680
|
| |
|