A lot of languages have adapted their default hash algorithms to address concerns about hash flooding. As I understand it, the argument is basically “better safe than sorry” when it comes to the default (since sometimes a library’s hash table might get used in unexpectedly sensitive places), coupled with the difficulty of using a non built-in hash in many high-level languages. Some relevant discussions from other languages:
- Python: Python adopts SipHash [LWN.net]
- Ruby: switch SipHash from SipHash24 to SipHash13 variant · ruby/ruby@04c94f9 · GitHub
- Rust: Remove (most) cryptographic algorithms from Rust by DaGenix · Pull Request #9744 · rust-lang/rust · GitHub, Change SipHash implementation to an optimized assembly version · Issue #35735 · rust-lang/rust · GitHub, consider using a different hash than SipHash for integer keys in rustc · Issue #10586 · rust-lang/rust · GitHub
- Java: Loading...
- Perl: The dangerous SipHash myth // perl11 blog
- Go: runtime: Extend Go's map crypto hash guarentee to all platforms in 1.5 · Issue #9365 · golang/go · GitHub, runtime: make aeshash more DOS-proof · golang/go@91059de · GitHub
Julia is in a somewhat different position than several of these languages, however, in that you can swap your own hash function into Julia’s Dict
type without any performance cost. Whereas in something like CPython the hash function is embedded in the C implementation and it’s not possible to use a different hash without either sacrificing performance, writing a huge pile of C code, or recompiling Python itself.
Even so, there is still a valid argument about coding defensively when writing library/package code.