Não existe uma “boa função hash” para hashes universais (ed. Sim, eu sei que existe algo como “hash universal”, mas não foi isso que eu quis dizer). Dependendo do contexto, diferentes critérios determinam a qualidade de um hash. Duas pessoas já mencionaram SHA. Este é um hash criptográfico e não é bom para tabelas de hash, o que você provavelmente quer dizer.
As tabelas de hash têm requisitos muito diferentes. Ainda assim, é difícil encontrar uma boa função de hash universalmente, porque tipos de dados diferentes expõem informações diferentes que podem ser hash. Como regra geral, é bom considerar todas as informações que um tipo mantém igualmente. Isso nem sempre é fácil ou até possível. Por razões de estatística (e, portanto, colisão), também é importante gerar uma boa dispersão no espaço do problema, ou seja, todos os objetos possíveis. Isso significa que, ao fazer o hash de números entre 100 e 1050, não é bom deixar o dígito mais significativo desempenhar um papel importante no hash porque, para ~ 90% dos objetos, esse dígito será 0. É muito mais importante deixar os três últimos dígitos determinam o hash.
Da mesma forma, ao fazer hash de strings, é importante considerar todos os caracteres - exceto quando se sabe de antemão que os três primeiros caracteres de todas as strings serão os mesmos; considerando estes, então, é um desperdício.
Este é realmente um dos casos em que aconselho a ler o que Knuth tem a dizer em The Art of Computer Programming , vol. 3. Outra boa leitura é The Art of Hashing, de Julienne Walker .