Skip to content

Instantly share code, notes, and snippets.

@msealand
Created October 28, 2014 02:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save msealand/49575c10aaf18042ab5f to your computer and use it in GitHub Desktop.
Save msealand/49575c10aaf18042ab5f to your computer and use it in GitHub Desktop.
Generate a random character from a range of characters (Unicode safe)
func randomCharacter<T: IntervalType where T.Bound == Character>(inRange range: T) -> Character {
let startScalars = String(range.start).unicodeScalars
let startCode = startScalars[startScalars.startIndex].value
let endScalars = String(range.end).unicodeScalars
let endCode = endScalars[endScalars.startIndex].value
let characterCount = distance(startCode, endCode) + 1
let rndOffset = Int(arc4random_uniform(UInt32(characterCount)))
return Character(UnicodeScalar(startCode + rndOffset))
}
@msealand
Copy link
Author

Example:

for i in 0..<10 {
    print(randomCharacter(inRange: "A"..."Z"))
}

LINCBKRGEN

@GhostViz
Copy link

This code was not working when I was trying to use it.

I kept getting an error: "Ambiguous use of operator '+'" on line 11.

The reason for this is rndOffset is being returned as an Int, but startCode is UInt32.

To fix this add Int() to startCode in line 11 so both startCode and rndOffset are of the same type.

func randomCharacter<T: IntervalType where T.Bound == Character>(inRange range: T) -> Character {
    let startScalars = String(range.start).unicodeScalars
    let startCode = startScalars[startScalars.startIndex].value

    let endScalars = String(range.end).unicodeScalars
    let endCode = endScalars[endScalars.startIndex].value

    let characterCount = distance(startCode, endCode) + 1
    let rndOffset = Int(arc4random_uniform(UInt32(characterCount)))

    return Character(UnicodeScalar(Int(startCode) + rndOffset))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment