Hi there,
Someone much more knowledgeable than me warned about using sets and dictionaries in Python as they can be hacked. I somewhat overlooked this advice as I assumed no one would hack a random pleb, but then I saw a warning in the editorial of 1915E - Romantic Glasses at https://codeforces.me/blog/entry/123952 state "Be careful about using hash tables, as they can be hacked."
One of the responses in that thread linked to https://codeforces.me/blog/entry/62393 which provided some insights and workarounds for C++, but is there such a resource for Python? Is there a general rule of thumb for using such data structures and finding the appropriate problem-specific alternative (such as a list of tuples, which will often do)?
Thanks in advance!








generate a random seed at runtime and xor it with each elem of set / key of dict
For example, instead of
set.add(x)u should doset.add(x^seed)where seed is a random integer that's generated at runtimeand when u wanna check membership, do
x^seed in setinstead ofx in setthis works cuz of the property $$$a \oplus a=0$$$
An example code is given for the problem "given a list of n integers and q queries, reply YES/NO depending on whether the queried elem is present in the list or not"
In order to hack this soln by hash collision, the hacker needs the value of seed. So, the probability of a successful hack is significantly low :)
Another method u can use is to just convert the integers into strings cuz python strings have randomized hash values across different runs... (in other words, python handles everything 4u if u use str instead of int)
but this runs slower than the xor method in some problems so try to use xor whenever possible...
the equivalent code in this method is
you can use a similar method for dict (
d[key^seed]=vto assign andd[key^seed]/d.get(key^seed,default)to read). u can also use the str methodMakes sense and very nice -- thanks!
I thought this approach was insufficient because it doesn't mix very well but in fact Python already has a built-in method for preventing collisions. It goes like this:
p = 2^61 - 1hash(x)for an integer is justx mod p2^kaccording to the size of the table. But then the funny part is that they use probing in the case of collisions and the probing depends on the entire hash.From CPython:
So this tries to makes it so that as long as your ints are <= 10^18, you are completely safe. It's still vulnerable if you particularly insert every key in the probing sequence of a key you want to slow down and then query the slow key a bunch of times, but xor probably actually introduces just enough mangling to prevent that. I will caution that in more low-level approaches (such as C++ just doing chaining or normal linear probing I think) that this is weak.
just use c++ man, in the long run the switch is worth it