4

I'm building a random password generator for iOS. In it, a button generates a random password that has characteristics chosen by the user (e.g. switches to turn on or off lowercase and uppercase letters, characters and symbols, and so on).

The UI looks great, the rest of the code is working smoothly, but I can't get my button to actually generate a random alphanumerical string. I have a label with some placeholder text ("Your Password") that should have its text updated to a random string when the button is pushed, but I am getting a compiler error: "unresolved use of identifier 'length'"

Here is the current code for the button:

@IBAction func generatePassword(_ sender: UIButton) {

    let randomPasswordArray: NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
    let len = UInt32(randomPasswordArray.length)

    var randomPassword = ""

    for _ in 0 ..< length {
        let rand = arc4random(len)
        var nextChar = randomPasswordArray.character(at: Int(rand))
        randomPassword += NSString(characters: &nextChar, length: 1) as String
    }

    passwordLabel.text = "randomPassword"
}

Thanks!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Justin Hodges
  • 185
  • 3
  • 10

3 Answers3

16

First create an array with your password allowed characters

let passwordCharacters = Array("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".characters)

then choose the password lenght

let len = 8 

define and empty string password

var password = ""

create a loop to gennerate your random characters

for _ in 0..<len {
    // generate a random index based on your array of characters count
    let rand = arc4random_uniform(UInt32(passwordCharacters.count))
    // append the random character to your string
    password.append(passwordCharacters[Int(rand)])
}
print(password)   // "V3VPk5LE"

Swift 4

You can also use map instead of a standard loop:

let pswdChars = Array("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
let rndPswd = String((0..<len).map{ _ in pswdChars[Int(arc4random_uniform(UInt32(pswdChars.count)))]})
print(rndPswd)   // "oLS1w3bK\n"

Swift 4.2

Using the new Collection's randomElement() method:

let len = 8
let pswdChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
let rndPswd = String((0..<len).compactMap{ _ in pswdChars.randomElement() })
print(rndPswd)   // "3NRQHoiA\n"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • That solved it. I had forgotten I used "len" instead of "length". Fixing it now, thank you for your help. – Justin Hodges Jan 19 '17 at 00:07
  • I think it'd be better to have numbers, symbols, uppercased and lowercased letter in different strings so it is easier to fulfil the secondary requirements of the password when required. – Ben Ong Jan 11 '18 at 03:29
  • I just fixed what was wrong at OP code. Sure I could simply separate lower and upper case element as well as numbers and symbols but OP didn't set any requirements like at least one lower, upper, number or .a symbol. You can also simply create a while loop to generate passwords until the requirements are met. If you need a password validator you can check this answer https://stackoverflow.com/questions/31954416/regex-for-alphanumeric-without-special-characters-swift-ios/31954533#31954533 – Leo Dabus Jan 11 '18 at 03:42
7

You can also use

import Security

let password = SecCreateSharedWebCredentialPassword() as String?
print(password)
manas sharma
  • 463
  • 1
  • 6
  • 8
0

Your code should be

...
for _ in 0 ..< len {
...
TheAmateurProgrammer
  • 9,252
  • 8
  • 52
  • 71