Other Posts in Randomization

  1. Random String/Password Generation in C#
  2. Lorem Ipsum Generator in C#
  3. Random Generation of Various Types

Random String/Password Generation in C#

11/24/2008

I'm guessing that someone out there has been in my position at some point in time... Basically I needed a password generator for a web site that I'm working on. I've seen a number of password generators out there and to be honest, I'm not a big fan of most of them. At the same time I couldn't use the default membership providers (long story as to why not). So basically I was stuck finding a way to generate my own random passwords (not to mention my own membership provider).

It's not a difficult task mind you, just annoying. That being said, I came up with the following class:

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Drawing;
  25: using System.Text;
  26: using System.Text.RegularExpressions;
  27: using Utilities.DataTypes;
  28: #endregion
  29:  
  30: namespace Utilities.Random
  31: {
  32:     /// <summary>
  33:     /// Utility class for handling random
  34:     /// information.
  35:     /// </summary>
  36:     public class Random : System.Random
  37:     {
  38:         #region Constructors
  39:  
  40:         /// <summary>
  41:         /// Constructor
  42:         /// </summary>
  43:         public Random()
  44:             : base()
  45:         {
  46:         }
  47:  
  48:         /// <summary>
  49:         /// Constructor
  50:         /// </summary>
  51:         /// <param name="Seed">Seed value</param>
  52:         public Random(int Seed)
  53:             : base(Seed)
  54:         {
  55:         }
  56:  
  57:         #endregion
  58:  
  59:         #region Public Functions
  60:  
  61:         /// <summary>
  62:         /// returns a random date/time for a specific date range.
  63:         /// </summary>
  64:         /// <param name="Start">Start time</param>
  65:         /// <param name="End">End time</param>
  66:         /// <returns>A random date/time between the start and end times</returns>
  67:         public DateTime NextDate(DateTime Start, DateTime End)
  68:         {
  69:             if (Start > End)
  70:             {
  71:                 throw new ArgumentException("The start value must be earlier than the end value");
  72:             }
  73:             return Start + new TimeSpan((long)(new TimeSpan(End.Ticks - Start.Ticks).Ticks * NextDouble()));
  74:         }
  75:  
  76:         /// <summary>
  77:         /// returns a randomly generated string
  78:         /// </summary>
  79:         /// <param name="Length">Length of the string</param>
  80:         /// <returns>a randomly generated string of the specified length</returns>
  81:         public string NextString(int Length)
  82:         {
  83:             if (Length < 1)
  84:                 return "";
  85:             return NextString(Length, ".");
  86:         }
  87:  
  88:         /// <summary>
  89:         /// Returns a randomly generated string of a specified length, containing
  90:         /// only a set of characters
  91:         /// </summary>
  92:         /// <param name="Length">length of the string</param>
  93:         /// <param name="AllowedCharacters">Characters that are allowed in the string</param>
  94:         /// <returns>A randomly generated string of the specified length, containing only the allowed characters.</returns>
  95:         public string NextString(int Length, string AllowedCharacters)
  96:         {
  97:             if (Length < 1)
  98:                 return "";
  99:             return NextString(Length, AllowedCharacters, Length);
 100:         }
 101:  
 102:         /// <summary>
 103:         /// Returns a randomly generated string of a specified length, containing
 104:         /// only a set of characters, and at max a specified number of non alpha numeric characters.
 105:         /// </summary>
 106:         /// <param name="Length">Length of the string</param>
 107:         /// <param name="AllowedCharacters">Characters allowed in the string</param>
 108:         /// <param name="NumberOfNonAlphaNumericsAllowed">Number of non alpha numeric characters allowed.</param>
 109:         /// <returns>A randomly generated string of a specified length, containing only a set of characters, and at max a specified number of non alpha numeric characters.</returns>
 110:         public string NextString(int Length, string AllowedCharacters, int NumberOfNonAlphaNumericsAllowed)
 111:         {
 112:             if (Length < 1)
 113:                 return "";
 114:             StringBuilder TempBuilder = new StringBuilder();
 115:             Regex Comparer = new Regex(AllowedCharacters);
 116:             Regex AlphaNumbericComparer = new Regex("[0-9a-zA-z]");
 117:             int Counter = 0;
 118:             while (TempBuilder.Length < Length)
 119:             {
 120:                 string TempValue = new string(Convert.ToChar(Convert.ToInt32(System.Math.Floor(94 * NextDouble() + 32))), 1);
 121:                 if (Comparer.IsMatch(TempValue))
 122:                 {
 123:                     if (!AlphaNumbericComparer.IsMatch(TempValue) && NumberOfNonAlphaNumericsAllowed > Counter)
 124:                     {
 125:                         TempBuilder.Append(TempValue);
 126:                         ++Counter;
 127:                     }
 128:                     else if (AlphaNumbericComparer.IsMatch(TempValue))
 129:                     {
 130:                         TempBuilder.Append(TempValue);
 131:                     }
 132:                 }
 133:             }
 134:             return TempBuilder.ToString();
 135:         }
 136:  
 137:         /// <summary>
 138:         /// Creates a Lorem Ipsum sentence.
 139:         /// </summary>
 140:         /// <param name="NumberOfWords">Number of words for the sentence</param>
 141:         /// <returns>A string containing Lorem Ipsum text</returns>
 142:         public string NextLoremIpsum(int NumberOfWords)
 143:         {
 144:             StringBuilder Builder = new StringBuilder();
 145:             Builder.Append(StringHelper.ToFirstCharacterUpperCase(Words[Next(Words.Length)]));
 146:             for (int x = 1; x < NumberOfWords; ++x)
 147:             {
 148:                 Builder.Append(" ").Append(Words[Next(Words.Length)]);
 149:             }
 150:             Builder.Append(".");
 151:             return Builder.ToString();
 152:         }
 153:  
 154:         /// <summary>
 155:         /// Creates a Lorem Ipsum paragraph.
 156:         /// </summary>
 157:         /// <param name="NumberOfParagraphs">Number of paragraphs</param>
 158:         /// <param name="MaxSentenceLength">Maximum sentence length</param>
 159:         /// <param name="MinSentenceLength">Minimum sentence length</param>
 160:         /// <param name="NumberOfSentences">Number of sentences per paragraph</param>
 161:         /// <param name="HTMLFormatting">Determines if this should use HTML formatting or not</param>
 162:         /// <returns>A string containing Lorem Ipsum text</returns>
 163:         public string NextLoremIpsum(int NumberOfParagraphs, int NumberOfSentences, int MinSentenceLength, int MaxSentenceLength, bool HTMLFormatting)
 164:         {
 165:             StringBuilder Builder = new StringBuilder();
 166:             if (HTMLFormatting)
 167:                 Builder.Append("<p>");
 168:             Builder.Append("Lorem ipsum dolor sit amet. ");
 169:             for (int y = 0; y < NumberOfSentences; ++y)
 170:             {
 171:                 Builder.Append(NextLoremIpsum(Next(MinSentenceLength, MaxSentenceLength))).Append(" ");
 172:             }
 173:             if (HTMLFormatting)
 174:                 Builder.Append("</p>");
 175:             for (int x = 1; x < NumberOfParagraphs; ++x)
 176:             {
 177:                 if (HTMLFormatting)
 178:                     Builder.Append("<p>");
 179:                 for (int y = 0; y < NumberOfSentences; ++y)
 180:                 {
 181:                     Builder.Append(NextLoremIpsum(Next(MinSentenceLength, MaxSentenceLength))).Append(" ");
 182:                 }
 183:                 if (HTMLFormatting)
 184:                     Builder.Append("</p>");
 185:                 else
 186:                     Builder.Append(System.Environment.NewLine).Append(System.Environment.NewLine);
 187:             }
 188:             return Builder.ToString();
 189:         }
 190:  
 191:         /// <summary>
 192:         /// Creates a Lorem Ipsum paragraph.
 193:         /// </summary>
 194:         /// <param name="NumberOfParagraphs">Number of paragraphs</param>
 195:         /// <param name="MaxSentenceLength">Maximum sentence length</param>
 196:         /// <param name="MinSentenceLength">Minimum sentence length</param>
 197:         /// <param name="NumberOfSentences">Number of sentences per paragraph</param>
 198:         /// <returns>A string containing Lorem Ipsum text</returns>
 199:         public string NextLoremIpsum(int NumberOfParagraphs, int NumberOfSentences, int MinSentenceLength, int MaxSentenceLength)
 200:         {
 201:             return NextLoremIpsum(NumberOfParagraphs, NumberOfSentences, MinSentenceLength, MaxSentenceLength, false);
 202:         }
 203:  
 204:         /// <summary>
 205:         /// Returns a random boolean value
 206:         /// </summary>
 207:         /// <returns>returns a boolean</returns>
 208:         public bool NextBool()
 209:         {
 210:             if (Next(0, 2) == 1)
 211:                 return true;
 212:             return false;
 213:         }
 214:  
 215:         /// <summary>
 216:         /// Gets a random enum value
 217:         /// </summary>
 218:         /// <typeparam name="T">The enum type</typeparam>
 219:         /// <returns>A random value from an enum</returns>
 220:         public T NextEnum<T>()
 221:         {
 222:             Array Values = Enum.GetValues(typeof(T));
 223:             int Index = Next(0, Values.Length);
 224:             return (T)Values.GetValue(Index);
 225:         }
 226:  
 227:         /// <summary>
 228:         /// Randomly generates a new time span
 229:         /// </summary>
 230:         /// <param name="Start">Start time span</param>
 231:         /// <param name="End">End time span</param>
 232:         /// <returns>A time span between the start and end</returns>
 233:         public TimeSpan NextTimeSpan(TimeSpan Start, TimeSpan End)
 234:         {
 235:             if (Start > End)
 236:             {
 237:                 throw new ArgumentException("The start value must be earlier than the end value");
 238:             }
 239:             return Start + new TimeSpan((long)(new TimeSpan(End.Ticks - Start.Ticks).Ticks * NextDouble()));
 240:         }
 241:  
 242:         /// <summary>
 243:         /// Returns a random color
 244:         /// </summary>
 245:         /// <returns>A random color between black and white</returns>
 246:         public Color NextColor()
 247:         {
 248:             return NextColor(Color.Black, Color.White);
 249:         }
 250:  
 251:         /// <summary>
 252:         /// Returns a random color within a range
 253:         /// </summary>
 254:         /// <param name="MinColor">The inclusive minimum color (minimum for A, R, G, and B values)</param>
 255:         /// <param name="MaxColor">The inclusive maximum color (max for A, R, G, and B values)</param>
 256:         /// <returns>A random color between the min and max values</returns>
 257:         public Color NextColor(Color MinColor, Color MaxColor)
 258:         {
 259:             return Color.FromArgb(Next(MinColor.A, MaxColor.A + 1),
 260:                 Next(MinColor.R, MaxColor.R + 1),
 261:                 Next(MinColor.G, MaxColor.G + 1),
 262:                 Next(MinColor.B, MaxColor.B + 1));
 263:         }
 264:  
 265:         #endregion
 266:  
 267:         #region Private Variables
 268:  
 269:         private string[] Words = new string[] { "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod",
 270:         "tempor", "invidunt", "ut", "labore", "et", "dolore", "magna", "aliquyam", "erat", "sed", "diam", "voluptua",
 271:         "at", "vero", "eos", "et", "accusam", "et", "justo", "duo", "dolores", "et", "ea", "rebum", "stet", "clita",
 272:         "kasd", "gubergren", "no", "sea", "takimata", "sanctus", "est", "lorem", "ipsum", "dolor", "sit", "amet",
 273:         "lorem", "ipsum", "dolor", "sit", "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod",
 274:         "tempor", "invidunt", "ut", "labore", "et", "dolore", "magna", "aliquyam", "erat", "sed", "diam", "voluptua",
 275:         "at", "vero", "eos", "et", "accusam", "et", "justo", "duo", "dolores", "et", "ea", "rebum", "stet", "clita",
 276:         "kasd", "gubergren", "no", "sea", "takimata", "sanctus", "est", "lorem", "ipsum", "dolor", "sit", "amet",
 277:         "lorem", "ipsum", "dolor", "sit", "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod",
 278:         "tempor", "invidunt", "ut", "labore", "et", "dolore", "magna", "aliquyam", "erat", "sed", "diam", "voluptua",
 279:         "at", "vero", "eos", "et", "accusam", "et", "justo", "duo", "dolores", "et", "ea", "rebum", "stet", "clita",
 280:         "kasd", "gubergren", "no", "sea", "takimata", "sanctus", "est", "lorem", "ipsum", "dolor", "sit", "amet", "duis",
 281:         "autem", "vel", "eum", "iriure", "dolor", "in", "hendrerit", "in", "vulputate", "velit", "esse", "molestie",
 282:         "consequat", "vel", "illum", "dolore", "eu", "feugiat", "nulla", "facilisis", "at", "vero", "eros", "et",
 283:         "accumsan", "et", "iusto", "odio", "dignissim", "qui", "blandit", "praesent", "luptatum", "zzril", "delenit",
 284:         "augue", "duis", "dolore", "te", "feugait", "nulla", "facilisi", "lorem", "ipsum", "dolor", "sit", "amet",
 285:         "consectetuer", "adipiscing", "elit", "sed", "diam", "nonummy", "nibh", "euismod", "tincidunt", "ut", "laoreet",
 286:         "dolore", "magna", "aliquam", "erat", "volutpat", "ut", "wisi", "enim", "ad", "minim", "veniam", "quis",
 287:         "nostrud", "exerci", "tation", "ullamcorper", "suscipit", "lobortis", "nisl", "ut", "aliquip", "ex", "ea",
 288:         "commodo", "consequat", "duis", "autem", "vel", "eum", "iriure", "dolor", "in", "hendrerit", "in", "vulputate",
 289:         "velit", "esse", "molestie", "consequat", "vel", "illum", "dolore", "eu", "feugiat", "nulla", "facilisis", "at",
 290:         "vero", "eros", "et", "accumsan", "et", "iusto", "odio", "dignissim", "qui", "blandit", "praesent", "luptatum",
 291:         "zzril", "delenit", "augue", "duis", "dolore", "te", "feugait", "nulla", "facilisi", "nam", "liber", "tempor",
 292:         "cum", "soluta", "nobis", "eleifend", "option", "congue", "nihil", "imperdiet", "doming", "id", "quod", "mazim",
 293:         "placerat", "facer", "possim", "assum", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing",
 294:         "elit", "sed", "diam", "nonummy", "nibh", "euismod", "tincidunt", "ut", "laoreet", "dolore", "magna", "aliquam",
 295:         "erat", "volutpat", "ut", "wisi", "enim", "ad", "minim", "veniam", "quis", "nostrud", "exerci", "tation",
 296:         "ullamcorper", "suscipit", "lobortis", "nisl", "ut", "aliquip", "ex", "ea", "commodo", "consequat", "duis",
 297:         "autem", "vel", "eum", "iriure", "dolor", "in", "hendrerit", "in", "vulputate", "velit", "esse", "molestie",
 298:         "consequat", "vel", "illum", "dolore", "eu", "feugiat", "nulla", "facilisis", "at", "vero", "eos", "et", "accusam",
 299:         "et", "justo", "duo", "dolores", "et", "ea", "rebum", "stet", "clita", "kasd", "gubergren", "no", "sea",
 300:         "takimata", "sanctus", "est", "lorem", "ipsum", "dolor", "sit", "amet", "lorem", "ipsum", "dolor", "sit",
 301:         "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod", "tempor", "invidunt", "ut",
 302:         "labore", "et", "dolore", "magna", "aliquyam", "erat", "sed", "diam", "voluptua", "at", "vero", "eos", "et",
 303:         "accusam", "et", "justo", "duo", "dolores", "et", "ea", "rebum", "stet", "clita", "kasd", "gubergren", "no",
 304:         "sea", "takimata", "sanctus", "est", "lorem", "ipsum", "dolor", "sit", "amet", "lorem", "ipsum", "dolor", "sit",
 305:         "amet", "consetetur", "sadipscing", "elitr", "at", "accusam", "aliquyam", "diam", "diam", "dolore", "dolores",
 306:         "duo", "eirmod", "eos", "erat", "et", "nonumy", "sed", "tempor", "et", "et", "invidunt", "justo", "labore",
 307:         "stet", "clita", "ea", "et", "gubergren", "kasd", "magna", "no", "rebum", "sanctus", "sea", "sed", "takimata",
 308:         "ut", "vero", "voluptua", "est", "lorem", "ipsum", "dolor", "sit", "amet", "lorem", "ipsum", "dolor", "sit",
 309:         "amet", "consetetur", "sadipscing", "elitr", "sed", "diam", "nonumy", "eirmod", "tempor", "invidunt", "ut",
 310:         "labore", "et", "dolore", "magna", "aliquyam", "erat", "consetetur", "sadipscing", "elitr", "sed", "diam",
 311:         "nonumy", "eirmod", "tempor", "invidunt", "ut", "labore", "et", "dolore", "magna", "aliquyam", "erat", "sed",
 312:         "diam", "voluptua", "at", "vero", "eos", "et", "accusam", "et", "justo", "duo", "dolores", "et", "ea",
 313:         "rebum", "stet", "clita", "kasd", "gubergren", "no", "sea", "takimata", "sanctus", "est", "lorem", "ipsum" };
 314:  
 315:         #endregion
 316:     }
 317: }

This class has a couple functions that it adds to the Random classes normal ones (NextDouble, etc.). The one that is probably of most interest is going to be NextString. That function takes in the length of the string that you want, a regular expression stating what characters are allowed, and the number of non alpha numeric characters. So for instance calling the function with this:

   1: NextString(10,"[0-9a-zA-Z_]",1);

That would create a random string of 10 characters that contained letters, numbers, and up to one underscore. The other functions are similar but with less control. For instance the one that just takes the length will use all characters on the ASCII table from 32 (space) up to 126 (~). But you can use this for quite a few items, passwords, testing, blog post generation when you're extremely bored and lazy... The list is rather endless... Anyway, I hope this helps someone out, so try out the code, leave feedback, and happy coding.



Comments