2017-03-08 69 views
3

我正在創建現有Android應用的iOS版本。 在Android端,String(username)的hashCode()被髮送到服務器,並基於該hash,返回一個JSON對象。在Swift 3中實現Java String的hashCode()方法

在Swift上,我嘗試了hash和hashValue屬性,但它們都產生了與Android對應的值不同的值。

所以我決定基於Java的實現,以寫我自己的實現:

int h = hash; 
if (h == 0 && value.length > 0) { 
    char val[] = value; 
    for (int i = 0; i < value.length; i++) { 
    h = 31 * h + val[i]; 
    } 
    hash = h; 
} 
return h; 

但是,當我寫斯威夫特上面的實現,我得到溢出崩潰。有人可以幫我嗎?

在此先感謝。

這裏是迅速實施:

我第一次寫一個字的擴展,將返回字符的ASCII值:

extension Character { 
    var asciiValue: UInt32? { 
     return String(self).unicodeScalars.filter{$0.isASCII}.first?.value 
    } 
} 

然後創建一個字符串與擴展: 1.屬性,該屬性返回String中每個字符的Ascii值。 2.散列方法返回哈希(複製Java代碼)

extension String { 
    var asciiArray: [UInt32] { 
     return unicodeScalars.filter{$0.isASCII}.map{$0.value} 
    } 
    func myHash() -> Int { 
     var h = 0 as Int! 
     for i in 0..<asciiArray.count { 
      h = 31*h! + Int(array[i]) 
     } 
     return h! 
    } 
} 
+0

而這正是您不應該使用散列值來識別多平臺系統上的對象的原因。爲什麼不直接使用用戶名或其他主鍵? – Alexander

+3

Swift溢出運算符'&+','&*'等完全是爲了這個目的。 –

+0

我正在編輯我的帖子以包含Swift實現 –

回答

1

默認情況下,迅速引發整數溢出異常(不像C或標準的Java整數操作)。爲了排除拋出異常,您必須使用爲其提供的特殊功能,如「addWithOverflow」。

另外你可以直接使用
-Ounchecked標誌

+1

'-Ounchecked'標誌禁止了更多的檢查,而不僅僅是溢出檢查(例如,數組越界等)。 –

+1

@SaagarJha是的,我同意這不是可取的。雖然我們在討論不適當的問題,但試圖複製本地字符串哈希可能只會以淚流滿 – Oscar

+0

看起來,它們正試圖在iOS和Android之間擁有一致的哈希值。 –

3

視後仍然缺少一個答案,這裏是工作代碼:

1)寫出字符的擴展名,繪製它們的ASCII表示爲int - 我們需要UInt32,因爲Java用於散列32位系統,而不是64位。

2)確保我們的代表字符串中只包含字符,可映射到ASCII

3)現在執行提到的散列函數

int h = 0; 
if (h == 0 && value.length > 0) { 
    char val[] = value; 
    for (int i = 0; i < value.length; i++) { 
    h = 31 * h + val[i]; 
    } 
    hash = h; 
} 
return h; 

因此,我們將得到下面的代碼片段,這可以在你的項目中使用。

// 1) Here is our Character extension 
extension Character { 
    var asciiValue: UInt32? { 
     return String(self).unicodeScalars.filter{$0.isASCII}.first?.value 
    } 
} 

extension String { 
    // 2) ascii array to map our string 
    var asciiArray: [UInt32] { 
     return unicodeScalars.filter{$0.isASCII}.map{$0.value} 
    } 

    // this is our hashCode function, which produces equal output to the Java or Android hash function 
    func hashCode() -> Int32 { 
     var h : Int32 = 0 
     for i in self.asciiArray { 
      h = 31 &* h &+ Int32(i) // Be aware of overflow operators, 
     } 
     return h 
    } 
}