The Daily WTF: Curious Perversions in Information Technology
Welcome to TDWTF Forums Sign in | Join | Help
in Search

Random Stupidity

Last post 03-12-2008 6:06 by RayS. 37 replies.
Page 1 of 1 (38 items)
Sort Posts: Previous Next
  • 02-23-2008 1:13 PM

    Random Stupidity

    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());
        }
    }
    
  • 02-23-2008 1:20 PM In reply to

    Re: Random Stupidity

    Ah, India....

    Reinventing methods poorly since 1999.

    I like how it doesn't even get a seed.

     

  • 02-23-2008 2:14 PM In reply to

    Re: Random Stupidity

     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... 

  • 02-23-2008 3:11 PM In reply to

    • lidden
    • Not Ranked
    • Joined on 02-06-2008
    • Posts 2

    Re: Random Stupidity

    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.

  • 02-23-2008 8:25 PM In reply to

    • JeffS
    • Not Ranked
    • Joined on 12-31-2007
    • near Cincinnati, USA
    • Posts 16

    Re: Random Stupidity

    PeriSoft:

    ... randomer...

     

     Heh.  New tach slang to use at our next dev meeting.  Randomer.

    Filed under:
  • 02-24-2008 1:14 In reply to

    Re: Random Stupidity

    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.

  • 02-24-2008 10:52 In reply to

    • ounos
    • Not Ranked
    • Joined on 02-24-2008
    • Posts 18

    Re: Random Stupidity

    WTF. getRandomNumberOfDigits does not even produce a uniform distribution. Knuth would be proud.

     

  • 02-24-2008 4:37 PM In reply to

    Re: Random Stupidity

    // 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? 

  • 02-24-2008 5:51 PM In reply to

    • Otac0n
    • Top 500 Contributor
    • Joined on 05-18-2005
    • Wichita, KS
    • Posts 77

    Re: Random Stupidity

    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
  • 02-25-2008 12:24 In reply to

    Re: Random Stupidity

    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.

     

  • 02-25-2008 2:02 PM In reply to

    Re: Random Stupidity

    public int random() {

        return 5; //chosen by a fair roll of the dice


     

  • 02-25-2008 2:48 PM In reply to

    • mfah
    • Top 500 Contributor
    • Joined on 12-01-2007
    • Posts 112

    Re: Random Stupidity

    More random randoms? Surely that's what uninitialized globals are for?
  • 02-25-2008 3:36 PM In reply to

    • KNY
    • Not Ranked
    • Joined on 07-19-2006
    • Posts 25

    Re: Random Stupidity

    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.
    Filed under:
  • 02-25-2008 6:30 PM In reply to

    Re: Random Stupidity

    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/ .  

    Filed under:
  • 02-26-2008 9:46 In reply to

    Re: Random Stupidity

    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.

    }

     

     

  • 02-26-2008 2:53 PM In reply to

    Re: Random Stupidity

    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.

  • 03-05-2008 7:17 In reply to

    Re: Random Stupidity

    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.

    Filed under:
  • 03-05-2008 11:47 In reply to

    Re: Random Stupidity

     So you modify it with something else, like say... the output of  /dev/random.

  • 03-05-2008 12:57 PM In reply to

    Re: Random Stupidity

    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
  • 03-05-2008 1:01 PM In reply to

    Re: Random Stupidity

    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
  • 03-05-2008 3:35 PM In reply to

    Re: Random Stupidity

    // 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... --
  • 03-05-2008 5:52 PM In reply to

    Re: Random Stupidity

    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.... 

    Filed under:
  • 03-06-2008 3:13 In reply to

    Re: Random Stupidity

    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.

  • 03-06-2008 5:38 In reply to

    • pscs
    • Not Ranked
    • Joined on 10-30-2007
    • Posts 40

    Re: Random Stupidity

    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.
  • 03-06-2008 10:08 In reply to

    • RayS
    • Top 25 Contributor
    • Joined on 01-22-2005
    • Posts 680

    Re: Random Stupidity