0

I am creating a simple class to generate fake lorem ipsum text so I have:

public static class LoremIpsumGenerator {

  private static Random _random = new Random();

  private static String _lorem = Constants.LoremIpsumText;
  private static IEnumerable<String> _words = _lorem.ToWordList();

  public static String GetText(Int32 totalLength = 200, Int32? paragraphLength = null) {

  IList<String> words = _words.OrderBy(x => Guid.NewGuid()).ToList();

  String text = String.Empty;
  String paragraph = _lorem.Substring(0, 12);

  Int32 index = 0;

  while (text.Length < totalLength) {

    //Int32 a = (paragraphLength == null ? _random.Next(20, 80) : paragraphLength.Value);

    Int32 limit = _random.Next(20, 80);

    while (paragraph.Length < limit) {

      paragraph += (String.IsNullOrEmpty(paragraph) ? words[index].ToFirstLetterUppercase() : words[index].ToLower()) + " ";        

      index++;

      if (index > words.Count)
        index = 0;

    }

    paragraph = paragraph.TrimEnd();
    text += paragraph + ". ";
    paragraph = String.Empty;

  }

  return text;

  } // GetText

} // LoremIpsumGenerator

The problem is in line:

Int32 l = (paragraphLength == null ? _random.Next(20, 80) : paragraphLength.Value);

It gives me almost always the same value ... For example I got:

21, 21, 47, 47, 47, 47, 47, 47, 47, 47, 47
or 
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50

Does anyone know how to prevent this?

UPDATE

public static class LoremIpsumGenerator {

  private static Random _random = new Random();

  private static String _lorem = Constants.LoremIpsumText;
  private static IEnumerable<String> _words = _lorem.ToWordList();

  public static String GetText(Int32 totalLength = 200, Int32? paragraphLength = null) {

  IList<String> words = _words.OrderBy(x => Guid.NewGuid()).ToList();

  String text = String.Empty;
  String paragraph = _lorem.Substring(0, 12);

  Int32 index = 0;

  while (text.Length < totalLength) {

    Int32 limit = _random.Next(20, 80);

    while (paragraph.Length < limit) {

      paragraph += (String.IsNullOrEmpty(paragraph) ? words[index].ToFirstLetterUppercase() : words[index].ToLower()) + " ";        

      index++;

      if (index > words.Count)
        index = 0;

    }

    paragraph = paragraph.TrimEnd();
    text += paragraph + ". ";
    paragraph = String.Empty;

  }

  } // GetText

} // LoremIpsumGenerator
Miguel Moura
  • 36,732
  • 85
  • 259
  • 481
  • 3
    Do you know that `paragraphLength` is null? – Lee Mar 01 '16 at 17:10
  • 1
    @Jonesopolis: That question is a bit different--the asker in that question is instantiating a new `Random` inside the loop, which this code is not doing. – Andrew Whitaker Mar 01 '16 at 17:12
  • Is more than one thread calling `GetText` at the same time, `Random` is not thread safe and you could potentially be calling `Next` from multiple threads which can break it and cause it to keep returning the same number. – Scott Chamberlain Mar 01 '16 at 17:12
  • @BenGlasser I dobut it is that either, he is getting the same number every time, that is a little bigger problem than trying to get a result with no duplicates. – Scott Chamberlain Mar 01 '16 at 17:14
  • Agree with @ScottChamberlain, indeed it's a very strange case if really is what is happening to the user. – Gusman Mar 01 '16 at 17:16
  • @Lee yes, paragraphLength is null – Miguel Moura Mar 01 '16 at 17:16
  • @Scott Chamberlain I am calling this from a test method – Miguel Moura Mar 01 '16 at 17:17
  • @Miguel, In your case I would split the inline if on two lines to be able to debug it more easily, also add the code where you checked these values are being the same to see if there is the problem. – Gusman Mar 01 '16 at 17:18
  • Show what you are doing inside `// loop code`, the problem must be there because I don't see any issues anywhere else. – Scott Chamberlain Mar 01 '16 at 17:19
  • this question scream this comic : http://resources.infosecinstitute.com/wp-content/uploads/121411_1611_SecureRando1.png – David Haim Mar 01 '16 at 17:20
  • MWAHAHAHA, very good @DavidHaim – Gusman Mar 01 '16 at 17:22
  • @ScottChamberlain See the update ... I just added my loop code ... And simplified my code with Int32 limit = _random.Next(20, 80); ... On the second while I added a debug breakpoint and got 70, 70, 70, 70, 70, 70, 70 ... – Miguel Moura Mar 01 '16 at 17:28
  • Are you sure the `Random` you are using is `System.Random` and not some other class named `Random` from some other DLL you have referenced or in another file in your project? That is the only thing I can think of. I would reccomend trying to simplifing the problem as much as you can, get rid of all of the text stuff and see how simple you can make the problem before Random starts working correctly again. then go back one step and post that program. – Scott Chamberlain Mar 01 '16 at 17:33
  • @Miguel seems like this describe your problem: you cannot generate random number instance [too fast](http://stackoverflow.com/questions/1654887/random-next-returns-always-the-same-values) – Ian Mar 01 '16 at 17:34
  • sorry to ask, but where are you adding your breakpoint? In `while (paragraph.Length < limit)`? If so, then you are not iterating over the outer "while", but on the inside, and you have not yet generated the next number. – Arturo Menchaca Mar 01 '16 at 17:38
  • I copy-pasted your updated code and ran it on my machine. I looked at `limit` on each run and I get different numbers on each call. Are you sure you aren't passing an unchanging `paragraphLength` when you call `GetText`? – Christopher Currens Mar 01 '16 at 17:40
  • Deleted previous comment: Indeed, I also get a different random number every time. Maybe you are looking at the debugger the wrong way: you won't get a different number for every time the inner loop gets executed. Only when you do the outer loop will you get a different number. – Kenneth Mar 01 '16 at 17:44
  • I restarted Visual Studio a tested it again and now it seems to work fine ... Is this even possible? – Miguel Moura Mar 01 '16 at 18:00

0 Answers0