在Xcode 10中构建时,重置应用后String.hashValue不唯一 [英] String.hashValue not unique after reset app when build in Xcode 10
问题描述
我有一个通过 String.hashValue
获取字符串的哈希"的代码,我在下面添加了它.该代码在Xcode 9.4.1中效果很好.
I have a "get hash of string by String.hashValue
" code, that I added it below. This code worked well in Xcode 9.4.1.
运作良好意味着,每当我关闭应用程序并重新打开它时, hashValue
的结果都是相同的(唯一的)
Worked well means that whenever I close app and re-open it, the result of hashValue
is same (unique)
private func cacheName(of url: String) -> String {
// The url is url of a png image, for example www.imageurl.com/image.png
return "\(url.hashValue)"
}
当我在Xcode 10中构建项目时,每次重新启动应用程序(关闭并再次打开应用程序)时,结果都会更改.iOS版本,设备版本,Swift版本相同.所以我认为问题是Xcode 10改变了一些影响 hashValue
的东西(可能在构建应用程序??时进行配置)
When I build my Project in Xcode 10 the result changes everytime I restart the app (close and open app again). The version of iOS, device, Swift version is same. So I think the problem is Xcode 10 has change something that effect to the hashValue
(maybe configure when build app ??)
如果我使用 String.hash
代替,则效果很好.但是在以前的版本中,我保存了 hashValue
结果,所以我不想更改它.
If I use the String.hash
instead of, it works well. But in the previous version, I saved the hashValue
result, so I don't want to change it.
如何始终保持 String.hashValue
的结果唯一.否则任何建议将不胜感激
How can I keep the result of String.hashValue
unique in every time. Or any suggestion would be appreciated
推荐答案
Swift 4.2已实现此处.
Swift 4.2 has implemented SE-0206: Hashable Enhancements. This introduces a new Hasher struct that provides a randomly seeded hash function. That's why the hashing results differ everytime (since the seed is random). You can find the implementation of the Hasher struct, with the generation of a random seed, here.
如果您想要一个与String关联的稳定哈希值,跨设备和应用启动,则可以使用此解决方案通过 Warren Stringer :
If you want a stable hash value associated to a String, accross devices and app lauches, you could use this solution by Warren Stringer:
let str = "Hello"
func strHash(_ str: String) -> UInt64 {
var result = UInt64 (5381)
let buf = [UInt8](str.utf8)
for b in buf {
result = 127 * (result & 0x00ffffffffffffff) + UInt64(b)
}
return result
}
strHash(str) //177798404835661
或者在字符串上定义这几个扩展名:
Or have these couple of extensions defined on String:
extension String {
var djb2hash: Int {
let unicodeScalars = self.unicodeScalars.map { $0.value }
return unicodeScalars.reduce(5381) {
($0 << 5) &+ $0 &+ Int($1)
}
}
var sdbmhash: Int {
let unicodeScalars = self.unicodeScalars.map { $0.value }
return unicodeScalars.reduce(0) {
(Int($1) &+ ($0 << 6) &+ ($0 << 16)).addingReportingOverflow(-$0).partialValue
}
}
}
"Hello".djb2hash //210676686969
"Hello".sdbmhash //5142962386210502930
(这是在Xcode 10,Swift 4.2上执行的)
这篇关于在Xcode 10中构建时,重置应用后String.hashValue不唯一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!