-2

can any one explain how does "arc4random()" method work internally?

my code is here :

randomDataName.derivation = [derivationArray objectAtIndex:(arc4random() %derivationCount)];
randomDataName.icon = [iconArray objectAtIndex:(arc4random() % iconCount)];
randomDataName.notes = [notesArray objectAtIndex:(arc4random() % notesCount)];
bobobobo
  • 64,917
  • 62
  • 258
  • 363
Shrey Soni
  • 45
  • 3

1 Answers1

10

arc4random uses Rivest Cipher 4. It a Substitution Cipher like the crudest Caesear Cipher. And for substitution it uses S-boxes which obviously expands as substitution boxes. In simple terms S-Boxes can be termed as lookup tables where you look for replacement of bytes. Read more on S-boxes.

An S-Box

And here the S-Boxes can be in 2^1700 different states (in simple words it can give that much variant substitution look-up tables, which generally can be a measure of cipher strength.). The whole process results in pseudo-random number, which means the numbers won't be truly random(I am not sure if true-random number generation is achieved yet.), i.e. the number will be dependent on something that was deterministic. And the function can give you any number in range 0-4294967296.

So what advantage it have over normal rand() and random()? it has a higher range (hopefully, more randomness than these two). But if you are using to get a small random number, the advantage diminishes, and I see you are doing it.

[derivationArray objectAtIndex:(arc4random() %derivationCount)]

So by modulo dividing the arc4random() output, you are restricting the final outcome to the range of 0 - derivationCount.

And that a lot of explanation!, but if you just want function definition, Read the manual!.

Edit from comments:

Instead of a modulo bias, use arc4random_uniform(). Still there is no guarantee, that the numbers won't be repeated.

egghese
  • 2,193
  • 16
  • 26
  • just superb explanation.... ty so much buddy – Shrey Soni Jul 20 '13 at 14:12
  • 4
    Just a note: You never want to use `arc4random()` with % to restrict the range. This introduces a modulo bias (some values are more likely than others). Instead, most systems that have `arc4random()` also have `arc4random_uniform()` which achieves the same goal without introducing a bias. – Rob Napier Jul 20 '13 at 14:22
  • "True randomness" is already achieved by [specialized hardware](http://stackoverflow.com/questions/658622/true-not-pseudo-random-number-generators-whats-out-there), but as long as the range of your RGN is large enough, you really shouldn't need _true_ randomness for most applications. – bobobobo Nov 18 '13 at 00:44
  • @RobNapier Modulo bias only comes into play if the number you are modding by is [very close to the RGN's maximum](http://stackoverflow.com/a/16006723/111307). If you are looking for a number between 0 and 3 (using `rand()%4`), and your RGN's output range is on `[0,5]`, then your chances for getting `[0,1,2,3]` are `[2/6, 2/6, 1/6, 1/6]` respectively. So the lower 2 numbers were more probable due to the use of `%` here. If however `RAND_MAX` is near 4,000,000,000, then this "modulo bias" all but disappears for small modulus. – bobobobo Nov 18 '13 at 00:50
  • @bobobobo: thanks for pointing out about achieving true randomness and detailed ref about module bias. I sure will look into the information you provided. – egghese Nov 18 '13 at 06:27
  • Also read the comments to @bobobobo's answer, which point out the problems with it. Yes, you can make the bias small and hope that it does not matter in your case (which means that you need to consider the problem *every time* you write a random number picker). Or by just using the correct function (`arc4random_uniform`), you can completely eliminate the problem in all cases. It is best to default to a simple, proven, reliable solution. – Rob Napier Nov 18 '13 at 14:39