import CryptoKit import Foundation private let idAlphabet = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") func newID(_ prefix: String) -> String { prefix + String((0..<11).map { _ in idAlphabet.randomElement()! }) } // IDs from before prefixed IDs were 12 lowercase hex characters; the server renamed each to this same derivation. func migratedID(_ prefix: String, _ old: String) -> String { guard old.count == 12, old.allSatisfy({ "0123456789abcdef".contains($0) }) else { return old } var n = SHA256.hash(data: Data(old.utf8)).prefix(8).reduce(UInt64(0)) { $0 << 8 | UInt64($1) } var out = "" for _ in 0..<11 { out.append(idAlphabet[Int(n % UInt64(idAlphabet.count))]) n /= UInt64(idAlphabet.count) } return prefix + out }