10 Replies Latest reply on May 18, 2009 12:03 PM by Miggl

    Best implementation of Math.random()?

    Miggl Level 1

      I'm trying to use Math.random to generate random strings. Unfortunately, the strings are not turning out to be very random, as I often get characters repeated.

       

      Here is the following formula I have been using:

      var result         :String  = "";
      var wordLength     :int     = 20;
      var characters     :String  = "abcdefgABCDEFG012345789";
      var set            :Array   = characters.split("");
      
      for (var i:int = 0; i < wordLength; i++)
      {
           result += set[int(Math.floor(Math.random() * set.length))];
      }
      

       

      Is there a better way to seed the Math.random() function to not use repeated results so often?

       

      Thanks!

        • 1. Re: Best implementation of Math.random()?
          injpix Level 3

          What exactly do you need this for?  Depending on your needs, you may be interested in mx.utils.UIDUtil class, which generates random strings in a specific format.

          • 2. Re: Best implementation of Math.random()?
            thebouv

            Well, what do you mean by your characters repeat?  If your computer could generate truly random numbers (it can't really), each of those letters would have a 1 in 24 chance of showing up, which is pretty good odds.  That's the thing about random, you see, you actually CAN randomly get the same characters several times in a row.  Even more so when you rely on something that isn't really random (random numbers from a computer processor).

             

            I copied your function and ran it multiple times.  Here is the content.  Looks decently random to me.

             

            4d4Beg0feAC5gd0CBF45
            49DFa2cgbAB9cgEe34F9
            Ge385g1gGaE0d7eCfD44
            D81B0e7F0fCbaCa51Ga1
            Ff2AgG158geb85b0bD0e
            aCB4CCF7CD993FF0g87C
            afd33b411BC4D3b447cC
            G3FBF85DACgDBa9Ga9A5
            0C348c78ad72cBgGE57f
            A53BfFA3GGa0eB9D1B7E
            509bfe9CEe49G3Bc1BgA
            aCE5D2AF3gB3CE2Ac8C0
            GcdEfDe90FEbAC2d8gDA
            e42F548333Fc9c3D319c
            CB2gA8eaC7eCGG783B8b
            D71GDdGf78fCCe90EFe3
            5BADFcEdBEeFfD3dGbb1
            DD43eDFbGbc5FagFcC01
            0bb7F02afacAADEC3Gfc
            fGC7D0C9De375GGAGGFb
            AD2c9A18bg5GC57GcBEA
            A94Beb371dA7AgFAB2eA
            A2b8C1a274cB8FCd994e
            Ddf7C428EAd1B2bDe1Eb
            dgA5e2Dgab3Bc39D31c1
            FDAC889bF47BgGGbb4G3
            BGC52g5c74Bg20BE284e
            988aaCgFbbbDa345G8cG
            2b31c37e3BA22E33Cg9d
            4Ac79EecA2BgdCa0GB71

            • 3. Re: Best implementation of Math.random()?
              Miggl Level 1

              I'm using this for a random password generator. My guess is that the UID function creates something akin to a windows GUID id?

              • 4. Re: Best implementation of Math.random()?
                Miggl Level 1

                Thanks for the detailed response with the examples! I guess I'm a bit stingy about the number of occurrences of sequences of same characters.

                 

                4d4Beg0feAC5gd0CBF45
                49DFa2cgbAB9cgEe34F9
                Ge385g1gGaE0d7eCfD44
                D81B0e7F0fCbaCa51Ga1
                Ff2AgG158geb85b0bD0e
                aCB4CCF7CD993FF0g87C
                afd33b411BC4D3b447cC
                G3FBF85DACgDBa9Ga9A5
                0C348c78ad72cBgGE57f
                A53BfFA3GGa0eB9D1B7E
                509bfe9CEe49G3Bc1BgA
                aCE5D2AF3gB3CE2Ac8C0
                GcdEfDe90FEbAC2d8gDA
                e42F548333Fc9c3D319c
                CB2gA8eaC7eCGG783B8b
                D71GDdGf78fCCe90EFe3
                5BADFcEdBEeFfD3dGbb1
                DD43eDFbGbc5FagFcC01
                0bb7F02afacAADEC3Gfc
                fGC7D0C9De375GGAGGFb
                AD2c9A18bg5GC57GcBEA
                A94Beb371dA7AgFAB2eA
                A2b8C1a274cB8FCd994e
                Ddf7C428EAd1B2bDe1Eb
                dgA5e2Dgab3Bc39D31c1
                FDAC889bF47BgGGbb4G3
                BGC52g5c74Bg20BE284e
                988aaCgFbbbDa345G8cG
                2b31c37e3BA22E33Cg9d
                4Ac79EecA2BgdCa0GB71

                 

                Multiple sequences of consecutive characters in a single result worries me a bit. But for the main part the result is random enough, and occasional sequences of repeated characters are acceptable.

                Today I was experiment with this, and ended up with instances of the same character occurring 5 times in a 10-digit result out of a set of 60+ characters. That to me is a bit too "unrandom", hence my worry.

                Of course, since I am using this for a password generator, you can always generate a new password if you don;t like it.

                 

                Would you try to improve on this, or move on and let it be what it is? My concern is being able to provide reasonably un-random passwords to my users, for security reasons.

                 

                Thanks!

                Mike

                • 5. Re: Best implementation of Math.random()?
                  Michael Borbor Level 4

                  If you're generating a password probably you'll be better off using symbols as well, and if your app is going to interact with a DB, probably checking that the generated password doesn't already exist will be a good idea. Also using not only lowercase but uppercase letters.

                  • 6. Re: Best implementation of Math.random()?
                    Miggl Level 1

                    Absolutely, this was just a general demo. The password generator is stand-alone, doesn't transmit results over internet, or use a database. Uses symbols, numbers, caps, lowercase, custom characters, and many more options.

                     

                    If you were to use this function for that purpose, would you be confident in its randomness? (I guess that's the question now, as there doesn't appear to be a "better" way to create random strings.)

                     

                    Thanks again!

                    -Mike

                    • 7. Re: Best implementation of Math.random()?
                      Michael Borbor Level 4

                      As thebouv said, it's all about probabilities, it's like flipping a coin, or playing to the Russian roulette, it all comes down to odds.

                      • 8. Re: Best implementation of Math.random()?
                        thebouv Level 2

                        It is not like any of the ones that you pointed out as having double characters makes it any easier to guess (by a human).

                         

                        If you want to feel safer, do as the other poster suggests and add some special characters in.

                         

                        The doubling of the characters does not make the algorithm you chose any less effective.  The number of choices remains 24 to the 20th.

                         

                        You could randomize between two choices, Heads and Tails, and hit Heads 100 times in a row.  The odds the 101st will be Heads is still the same as the first one.

                         

                        Good luck!

                        • 9. Re: Best implementation of Math.random()?
                          Barna Biro Level 3

                          Hi there,

                           

                          I'd personally create a utility class that returns a randomly generated string with the help of at least 2 passed parameters. I threw together an example on this, I'll post the source code here and also a .zip file with the projet ( it's an ActionScript project ):

                           

                          package
                          {
                              import com.adobeforum.utils.StringUtil;
                              
                              import flash.display.Sprite;
                          
                              public class RandomString extends Sprite
                              {
                                  /**
                                  * @private
                                  * The list of characters that must be used to generate
                                  * the random <code>String</code>.
                                  */
                                  private var _restrict:String = "abcdefgABCDEFG012345789";
                                  
                                  /**
                                  * Constructor.
                                  */
                                  public function RandomString()
                                  {
                                      // Generate 20 random strings.
                                      for (var i:int = 0; i < 20; i++)
                                      {
                                          trace("Random value: " + StringUtil.generateRandomString(10, _restrict));
                                      }
                                  }
                              }
                          }
                          

                           

                          And here's the utility class that makes the magic happen ( I hope I understood your problem right; in case not, then you can simply add your own conditions there to achieve the desired result ):

                           

                          package com.adobeforum.utils
                          {
                              public class StringUtil
                              {       
                                  /**
                                  * @private
                                  * Holds the list of restricted characters.
                                  */
                                  private static var _restrictedCharacters:Array = null;
                                  
                                  /**
                                  * @private
                                  * Holds the last generated random character.
                                  */
                                  private static var _randomChar:String = "";
                                  
                                  /**
                                  * @private
                                  * Will hold the generated random <code>String</code>.
                                  */
                                  private static var _randomString:String = "";
                                   
                                  /**
                                  * Used to generate a random <code>String</code> of a specific length.
                                  * 
                                  * @param leng The desired length of the final <code>String</code>.
                                  * @param restrict This value holds the characters that should be used to
                                  * generate the final result.
                                  */
                                  public static function generateRandomString(leng:int, restrict:String):String
                                  {
                                      // Check if we have sufficient information to generate a random String.
                                      if (restrict.length < 2 || leng < 2) return "";
                                      
                                      resetToDefault();
                                      _restrictedCharacters = restrict.split("");
                                      
                                      // Keep adding to the final string until it's length is less than
                                      // the desired length that was passed to the method.
                                      while (_randomString.length < leng)
                                      {
                                          // Get a random character and the last character of the existing string.
                                          var randomChar:Number = randomChar().charCodeAt();
                                          var lastChar:Number = lastChar().charCodeAt();
                                          
                                          // If the two values do not match then add the random character to the existing string. 
                                          if (randomChar != lastChar) _randomString += _randomChar;
                                      }
                                      
                                      return _randomString;
                                  }
                                  
                                  /**
                                  * @private
                                  * Get a random character from the list of restricted characters.
                                  */
                                  private static function randomChar():String
                                  {
                                      // Check if the restricted characters list exists and is not empty.
                                      if (_restrictedCharacters.length == 0 || _restrictedCharacters == null) return "";
                                      
                                      // Get the random character from the list.
                                      var randomIndex:int = (Math.random() * _restrictedCharacters.length) >> 0;
                                      var randomChar:String = _restrictedCharacters[randomIndex].toString();
                                      _randomChar = randomChar;
                                       
                                      return randomChar;
                                  }
                                  
                                  /**
                                  * @private
                                  * Get the last character of the existing random <code>String</code>.
                                  */
                                  private static function lastChar():String
                                  {
                                      // Make sure that the string exists.
                                      if (_randomString.length == 0 || _randomString == null) return "";
                                      return _randomString.slice(_randomString.length - 1, _randomString.length).toString();
                                  }
                                  
                                  /**
                                  * @private
                                  * Used to reset the <code>static</code> variables so that the methods
                                  * will always function correctly and won't use values that might have been set
                                  * with a previous call.
                                  */
                                  private static function resetToDefault():void
                                  {
                                      _randomChar = "";
                                      _randomString = "";
                                      _restrictedCharacters = null;
                                  }
                              }
                          }
                          

                           

                          A small and quite handy class, hope it helps.

                           

                          With best regards,

                          Barna Biro

                          Blog: http://blog.wisebisoft.com

                           

                          EDIT: I almost forgot to upload the archive. It seems that I can't upload .zip files directly so you'll need to download it from here: http://www.mediafire.com/?sharekey=8b560ca4d7ac122a6b21be4093fab7ace04e75f6e8ebb871

                           

                          One more thing, in the example I am generating the string with "case sensitiv" comparition in mind. So "c" != "C". In case you want to don't case about case sensitivity then replace the charcode comparition and simply compare 2 string that are converted to lowercase before comparition.

                           

                          EDIT: I didn't see this: G3FBF85DACgDBa9Ga9A5 at first. Well, this is a more delicate situations and to get a string that is generated in a way so that a certain pair is not found more than once in the whole string is quite tricky. Not sure if an algorythm exists on this but you can google and see what you find. To be honest, you'd be just wasting time by adding stuff like this, even with the stuff I posted. If someone wants to hack into your system, trust me, he will, no matter what you have or haven't got there ( and your "hyper random" string will definitely not be a challange ). Obvioiusly, this doesn't mean that we can't add some security features but in my opinion, a simple random string is more than enough, the rest is just waste of time.

                          1 person found this helpful
                          • 10. Re: Best implementation of Math.random()?
                            Miggl Level 1

                            Hi Barna,

                             

                            Thanks for your detailed reply. I in fact already have broken everything out into its own libraries and such. Thanks very much for posting your code though, it's increadibly helpful to see how others code.

                             

                            Cheers!

                            Mike