Skip to content

Instantly share code, notes, and snippets.

@bendodson
Last active January 25, 2024 17:05
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bendodson/bbb47acb3c31cdb6e87cdec72c63c7eb to your computer and use it in GitHub Desktop.
Save bendodson/bbb47acb3c31cdb6e87cdec72c63c7eb to your computer and use it in GitHub Desktop.
Generate a random color with a seed string using Swift 3
import UIKit
func randomColor(seed: String) -> UIColor {
var total: Int = 0
for u in seed.unicodeScalars {
total += Int(UInt32(u))
}
srand48(total * 200)
let r = CGFloat(drand48())
srand48(total)
let g = CGFloat(drand48())
srand48(total / 200)
let b = CGFloat(drand48())
return UIColor(red: r, green: g, blue: b, alpha: 1)
}
// Identical seeds will lead to identical colors
randomColor(seed: "ben")
randomColor(seed: "ben")
// Similarly, seeds with the same character values will lead to identical colors
randomColor(seed: "ben")
randomColor(seed: "neb")
// However, this works well enough for something like article titles
randomColor(seed: "iPhone 7: Jet Black vs. Black")
randomColor(seed: "Vesper, Adieu")
randomColor(seed: "Bloomberg’s Report on Apple Watch 2")
randomColor(seed: "Is Donald Trump Actually Trying to Win?")
randomColor(seed: "Uber to Begin Testing Self-Driving Cars in Pittsburgh")
randomColor(seed: "Apple and the Pistol Emoji")
randomColor(seed: "Jack Off")
randomColor(seed: "Headphone Jacks Are the New Floppy Drives")
randomColor(seed: "Brief Thoughts and Observations Regarding Today’s WWDC 2016 Keynote")
randomColor(seed: "App Store Subscription Uncertainty")
@LeoNatan
Copy link

Why not use String.hash instead of sum of scalars? It will bring you more entropy and will solve your case for ben and neb.

@bwised
Copy link

bwised commented Jan 25, 2024

Hashing is now randomly seeded per application instance, per https://forums.swift.org/t/psa-the-stdlib-now-uses-randomly-seeded-hash-values/10789. So using String.hash will produce different results per application run, which defeats the purpose of using a seed completely.

What I did to deal with the "neb" vs "ben" problem is add the position of the scalar to the seed.

...
        var seed: Int = 0
        var i = 1
        for u in self.unicodeScalars {
            seed += Int(UInt32(u)) + i // add the position so that "ben" and "neb" do not produce the same seed
            i += 1
        }
...

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