# 不及格的程序员-八神 # rand(3) / random(3) / arc4random(3) / et al.

## Written by Mattt Thompson on August 12th, 2013

What passes for randomness is merely a hidden chain of causality.

In a mechanical universe of material interactions expressed through mathematical equations, it is unclear whether nature encodes an element of chance, or if it's a uniquely human way to reconcile uncertainty.

We can be sure of one thing, however: in the closed, digital universe of CPU cycles, processes, and threads, there is no true randomness, only pseudorandomness.

Pseudorandomness, is often implemented in a way very similar to a cryptographic hash, as a deterministic function that returns a value based on the current time (salted, of course, by some initial seed value). Also like hash functions, there are a number of PRNG, or pseudorandom number generators, each of which are optimized for particular performance characteristics: uniformity, periodicity, and computational complexity.

Of course, for app developers, all of this is an academic exercise. And rather than bore you with any more high-minded, long-winded treatises on the philosophical nature of randomness, we're going to tackle this one FAQ-style.

Our goal this week: to clear up all of the lingering questions and misunderstandings about doing random things in Objective-C. Let's dive in!

## How Do I Generate a Random Number in Objective-C?

tl;drUse arc4random() and its related functions.

Specifically, to generate a random number between 0 and N - 1, use arc4random_uniform(), which avoids modulo bias.

### Random int between 0 and N - 1

Objective-C
NSUInteger r = arc4random_uniform(N);


### Random int between 1 and N

Objective-C
NSUInteger r = arc4random_uniform(N) + 1;


### Random double between 0 and 1

If you are generating a random double or float, another good option is the more obscure rand48family of functions, including drand48(3).

Objective-C
srand48(time(0));
double r = drand48();


rand48 functions, unlike arc4random functions, require an initial value to be seeded before generating random numbers. This seed function, srand48(3), should only be run once.

## How Do I Pick a Random Element from an NSArray?

Use arc4random_uniform(3) to generate a random number in the range of a non-empty array.

Objective-C
if ([array count] > 0) {
id obj = array[arc4random_uniform([array count])];
}


## How Do I Randomly Order an NSArray?

Objective-C
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
NSUInteger count = [mutableArray count];
// See http://en.wikipedia.org/wiki/Fisher–Yates_shuffle
if (count > 1) {
for (NSUInteger i = count - 1; i > 0; --i) {
[mutableArray exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform((int32_t)(i + 1))];
}
}

NSArray *randomArray = [NSArray arrayWithArray:mutableArray];


This code is borrowed from TTTRandomizedEnumerator, which also provides randomized enumerators for NSSetNSOrderedSet, and NSDictionary.

## How Do I Generate a Random String?

If you're looking to generate "lorem ipsum"-style sentences, try constructing a Markov Chain from a corpus.

Otherwise, if you're looking to just get random letters, try one of the following methods:

### Generate a Random Lowercase NSString

If you are operating on a known, contiguous range of Unicode characters, such as the lowercase letters (U+0061 — U+007A), you can do a simple conversion from a char:

Objective-C
NSString *letter = [NSString stringWithFormat:@"%c", arc4random_uniform(26) + 'a'];


### Pick a Random Character From an NSString

Otherwise, a simple way to pick random letters from a set of your choosing is to simply create a string containing all of the possible letters:

Objective-C
NSString *vowels = @"aeiouy";
NSString *letter = [vowels substringWithRange:NSMakeRange(arc4random_uniform([vowels length]), 1)];


## Why Should I Use arc4random(3) instead of rand(3) or random(3)?

C functions are typically denoted with a number 3 inside of parentheses, following the organizational convention of man pages.

• arc4random does not require an initial seed (with srand or srandom), making it that much easier to use.
• arc4random has a range up to 0x100000000 (4294967296), whereas rand and random top out at RAND_MAX = 0x7fffffff (2147483647).
• rand has often been implemented in a way that regularly cycles low bits, making it more predictable.

## What are rand(3), random(3), and arc4random(3), and Where Do They Come From?

If you have any additional questions about randomness on Objective-C, feel free to tweet @NSHipster. As always, corrections are welcome in the form of a pull request.

JavaScript Math.random() 函数

 1 2 Math.random()*(n-m)+m； 改正公式:Math.random()*(n+1-m)+m
 1 document.write(Math.random());

 1 document.write(Math.random()*(20-10)+10);

 1 document.write(Math.random()*(n+1-m)+m);

/// <summary>
/// 获取指定区间的随机数
/// </summary>
/// <param name="min">The minimum.</param>
/// <param name="max">The maximum.</param>
/// <returns></returns>
public static int GetRandom(int min = 0, int max = 30)
{
return new Random(GetRandomSeed()).Next(min, max+1);
}

/// <summary>
/// 加密随机数生成器 生成随机种子
/// </summary>
/// <returns></returns>
public static int GetRandomSeed()
{

byte[] bytes = new byte;

System.Security.Cryptography.RNGCryptoServiceProvider r = new System.Security.Cryptography.RNGCryptoServiceProvider();

r.GetBytes(bytes);

return BitConverter.ToInt32(bytes, 0);

}

posted on 2015-01-27 14:32 不及格的程序员-八神 阅读(...) 评论(...) 编辑 收藏