0

Im generating a random number string using

int rNumber = rand() %100000000 + 1;
_certificateReferenceField.text = [[NSString alloc] initWithFormat: @"C/R %d", rNumber];

When the app is first launched or comes from being in the background it always picks the same number initially c/R16808? Press it again and no problem, all works fine.

JSA986
  • 5,870
  • 9
  • 45
  • 91

3 Answers3

5

rand() is not a good random number generator, do this

NSInteger rNumber = arc4random() % 100000000 + 1;
Kaan Dedeoglu
  • 14,765
  • 5
  • 40
  • 41
  • There's nothing wrong with `rand`. Some will argue that `arc4random` is overkill. It depends on the needs. – rmaddy Jan 04 '13 at 19:16
  • 1
    You're right, depends on the case, one weak part of rand is unless you seed it every time, the sequence of numbers generated by repeatedly calling rand() will be easily predictable. – Kaan Dedeoglu Jan 04 '13 at 19:18
  • But still arc4random() gives you same value in each run. – Anoop Vaidya Jan 04 '13 at 19:21
  • @maddy, yes but you'd have to call this (srand()) every time, and then call rand(). Which makes it 2 lines – Kaan Dedeoglu Jan 04 '13 at 19:21
  • 1
    @AnoopVaidya that is simply not correct. arc4random() seeds itself every time you call it. – Kaan Dedeoglu Jan 04 '13 at 19:22
  • Thanks Kaann, still getting 1608 initially – JSA986 Jan 04 '13 at 19:23
  • I have tested in my app by writing all random numbers in a file. and after 1000 run, same answer. :( – Anoop Vaidya Jan 04 '13 at 19:25
  • 1
    @KaanDedeoglu No, you only call `srand` once when the app starts. Not for every call of `rand`. I just ran some tests. `arc4random` is 3 times slower than `rand`. – rmaddy Jan 04 '13 at 19:30
  • @maddy I get your point, of course, what I was trying to say is this:if I know the first number you produce with rand(), then I can know all the following numbers. rand() just seeds itself with the last produced number. So it's very unsafe for some applications. – Kaan Dedeoglu Jan 04 '13 at 19:40
  • @KaanDedeoglu But that's not true if `rand` is properly seeded with `srand`. Then you don't know what the first call to `rand` will return. So it is perfectly safe. But again, it depends on the need. `arc4random` is a much better choice for dealing with security and cryptography. If you simply want to put a view in a random spot on the screen, for example, `rand` is perfect and far more efficient than `arc4random`. – rmaddy Jan 04 '13 at 19:46
  • @maddy Once your first call returns (let's say) 32, I know that the sequence will go 32-537824-449273380-385194808-etc... Your answer is more justified in a general use case, I just sleep better at night with arc4random() :) – Kaan Dedeoglu Jan 04 '13 at 19:52
1

You need to seed the random number generator using srand. A common use is:

srand(time(NULL));

Call this before any call to rand.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • tnaks Maddy but srand(time(NULL)); int rNumber = rand() %100000000 + 1; _certificateReferenceField.text = [[NSString alloc] initWithFormat: @"C/R %d", rNumber]; still give sme 1608 for some reason initially – JSA986 Jan 04 '13 at 19:23
  • why not `srandomdev(void);`? – ZhangChn Jan 04 '13 at 19:23
  • @JSA986 When I use `srand` on app startup, each call to `rand` gives me a different number each time the app is run. – rmaddy Jan 04 '13 at 19:33
  • I'd put the call to `srand` in `main` or your app delegate's `init` method. – rmaddy Jan 04 '13 at 19:35
  • Maddy Ive got it in `didFinishLaunchingWithOption` if thats correct? So am i right in thinking that always sets the initial string to zero before randomising it with `srand(time(NULL));` – JSA986 Jan 04 '13 at 19:39
  • That's a good place too. Calling `srand` does nothing to a string. It just ensures that calls to `rand` give you a different sequence of values each time the app is run. – rmaddy Jan 04 '13 at 19:42
0

You can use

srandom(time(NULL));

to randomize your random number generation.

and then use random() to generate random numbers.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140