Skip to content

Instantly share code, notes, and snippets.

@msewell
Last active June 23, 2020 13:52
Show Gist options
  • Save msewell/d40260d336bae58bf1649be1303dc974 to your computer and use it in GitHub Desktop.
Save msewell/d40260d336bae58bf1649be1303dc974 to your computer and use it in GitHub Desktop.
Generate a color from a string (deterministically)
import UIKit
extension UIColor {
/// Generate a color from the given string deterministically.
///
/// Generated colors are *not* evenly distributed in the HSL color space, but you and/or your users also probably won't be able to tell.
convenience init(_ string: String, saturation: Double = 0.8, brightness: Double = 0.8) {
let seed = Double.pi // Can be any positive irrational number. Pi was chosen for flavor.
let hash = string
.compactMap { $0.unicodeScalars.first?.value.byteSwapped }
.map(Double.init)
.reduce(seed) { (hash, unicodeValue) in
return (hash * seed * unicodeValue)
.truncatingRemainder(dividingBy: 360)
}
let hue = hash / 360
self.init(hue: CGFloat(hue), saturation: CGFloat(saturation), brightness: CGFloat(brightness), alpha: 1.0)
}
}
// These should all look different.
UIColor("")
UIColor("0")
UIColor("00")
UIColor("000")
UIColor("1")
UIColor("1", saturation: 0.4)
// Long and Unicode strings are fine, too.
UIColor("以呂波耳本部止千利奴流乎和加餘多連曽津祢那良牟有為能於久耶万計不己衣天阿佐伎喩女美之恵比毛勢須")
// Colors are deterministic.
assert(UIColor("apples") == UIColor("apples"))
assert(UIColor("apples") != UIColor("oranges"))
assert(UIColor("apples", saturation: 1.0) != UIColor("apples", saturation: 0.9))
assert(UIColor("apples", brightness: 1.0) != UIColor("apples", brightness: 0.9))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment