2013-11-26 61 views
3

我想存儲在地圖對象包裝網絡連接,其中密鑰應該是IP地址+端口號。std :: unordered_map和關鍵內置的多個元素

我的問題是我應該如何處理這兩個元素的關鍵?

我可以定義std::unordered_map<std::pair<std::string, uint16_t>, Connection>,但我不知道該如何實現散列對象。我的腦海裏只有天真的實現:

std::size_t operator() (const pair<std::string, uint16_t>& key) const 
{ 
    std::hash<std::string> ip_hash; 
    std::hash<uint16_t> port_hash; 

    return ip_hash (key.first) + port_hash (port.second); 
} 

我假設兩個散列值的簡單添加是相當糟糕的主意。在實現哈希函數時,我是否應該遵守任何一般規則?

(我知道,我可以從IP地址和端口號建立一個字符串,但我只是好奇)。

+0

如果您解釋了「ip_hash」和「port_hash」的含義,提供建議會更容易。尤其是後者 - 一個端口號可以很好地用作自己的散列(即散列==標識)。如果您不希望來自同一個IP地址的多個連接,您甚至可以完全避免使用該端口。 – Jon

+0

@Jon好吧,我將有來自同一個IP的多個連接,因爲這個軟件將在局域網中與幾個NAT一起使用。 – Goofy

+0

該解決方案看起來不錯,但我會結合這些值使用XOR而不是加法,因爲添加會混淆分佈。 – Johan

回答

1

如果使用boost是一個選項,boost::hash_combine使這非常容易(否則該實現可在鏈接頁面上獲得)。

std::size_t operator()(const pair<std::string, uint16_t>& key) const 
{ 
    std::size_t seed = 0; 
    boost::hash_combine(seed, key.first); 
    boost::hash_combine(seed, key.second); 
    return seed; 
} 
1

一個簡單的解決方案是將uint16_t端口號附加到表示IP地址的字符串。然後你可以使用std:unordered_map<string, Connection>

0

對於非安全性實踐,您的哈希大多數都是很好的。您可以通過以下方式使其更加健壯:

struct ip_port_hash 
{ 
    size_t operator() (const std::pair< std::string, uint16_t >& key) const 
    { 
     std::hash<const char*> ip_hash; 
     std::hash<size_t>  size_t_hash; 

     return size_t_hash(ip_hash (key.first.c_str()) + key.second); 
    } 
};