views:

588

answers:

2

Hey there,

I know this can't be that hard. I've searched, but I can't seem to find a simple solution. I want to call a method, pass it the length and have it generate a random alphanumeric string.

Any ideas? Are there any utility libraries out there that may have a bunch of these types of functions?

Thanks, Howie

+3  A: 

Here's a quick and dirty implementation. Hasn't been tested.

NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

-(NSString *) genRandStringLength: (int) len {

    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];

    for (int i=0; i<len; i++) {
         [randomString appendFormat: @"%c", [letters characterAtIndex: rand()%[letters length]] )
    }

    return randomString;
}
Jeff B
genRandStringLength should just return randomString. There's no reason to alloc and init (and not autorelease!) a whole new string.
kevingessner
Fixed. Should the return type be NSMutableString? Or is it fine with NSString?
Jeff B
`NSString` is fine.
Rob Keniger
This is a useful macro to get a very random number: `#define RKRandom(x) (arc4random() % ((NSUInteger)(x) + 1))`
Rob Keniger
Just going to put this out there. There's no reason to use an `NSString` for `letters` when a simple `char` array would work just fine. In fact, using `[letters characterAtIndex:(rand() % [letters length])]` seems to me to be less concise than just `letters[rand() % strlen(letters)]`. The Foundation classes are really helpful, but for the simplest things, they can serve to obfusticate our code rather than enhance it.
Jonathan Sterling
@kevingessner Technically, in general, you should probably return [[randomString copy] autorelease]. This is because you then get an immutable result which cannot be changed deliberately or accidentally by other code.
JeremyP
@JeremyP - I guess. I'm not that [randomString copy] will return an actually immutable string; that's an implementation detail. Since genRandStringLength is defined to return an NSString, it doesn't matter that it's "actually" an NSMutableString; any code that tries to change it is wrong.
kevingessner
@Jonathan: I actually started with exactly what you suggested in fact. I am trying to learn to do things with the Foundation classes, however, so I rewrote it the other way. I agree, it might be overkill in this case, but it is an example of how to go about it the "objective-c way".
Jeff B
@kevingessner -copy returns an immutable object "if the consideration “immutable vs. mutable” applies to the receiving object" - from the documentation of NSCopying. As regards mutable versus immutable, I agree that, in this case, the difference is marginal, but if other code does accidentally send -appendString to the return result, the resulting invalid selector exception is easier to debug than a mysterious and unexplained change in a string you weren't expecting.
JeremyP
+2  A: 

You could also just generate a UUID. While not truly random, they are complex and unique which makes them appear random for most uses. Generate one as a string and then take a range of characters equal to the passed length.

TechZen