3

I'd like to store in map objects wrapping network connections, where key should be IP address + port number.

My question is how should I handle such key with two elements?

I can define std::unordered_map<std::pair<std::string, uint16_t>, Connection>, but I'm not sure how should I implement hash object for it. Only naive implementation comes to my mind:

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);
}

I assume that simple addition of two hash values is rather bad idea. Are there any general rules that i should obey to when implementing hash functions?

(I know, that i can build a string from IP address and port number, but I'm just curious).

3
  • It would be easier to offer suggestions if you explained what you have in mind for ip_hash and port_hash. Especially the latter -- a port number can serve excellently as its own hash (i.e. hash == identity). If you don't expect many connections from the same IP address you can even take the port out of the equation entirely. Commented Nov 26, 2013 at 23:32
  • @Jon Well, I will have multiple connections from the same IP, because this software is going to be used in LAN with couple NATs. Commented Nov 26, 2013 at 23:58
  • The solution looks ok, but I would combine the values using xor instead of addition since addition will mess up the distribution. Commented Nov 30, 2017 at 11:15

3 Answers 3

1

If using boost is an option, boost::hash_combine makes this really easy (otherwise the implementation is available on the linked page).

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

A trivial solution will be to append the uint16_t port number to the string, representing the IP address. Then you can use std:unordered_map<string, Connection>.

Comments

0

Your hashing is mostly fine for non security practices. You can make it more robust this way:

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);
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.