-4

In the following code.

>>> hash('bar')
327024216814240868
>>> hash('baz')
327024216814240876
>>> hash('bar') % 8
4
>>> hash('baz') % 8
4

bar and baz, however, have hash values that are exactly 8 apart and thus map to the exact same slot, 4:

Their order now depends on which key was slotted first; the second key will have to be moved to a next slot:

>>> {'baz': None, 'bar': None}
{'bar': None, 'baz': None}
>>> {'bar': None, 'baz': None}
{'baz': None, 'bar': None}

But here both the outputs must be same as hash value of bar comes before than baz.
I meant,

>>>{'bar': None, 'baz': None}

should come,

{'bar': None, 'baz': None}
ashish verma
  • 13
  • 1
  • 5
  • 2
    http://stackoverflow.com/questions/14956313/dictionary-ordering-non-deterministic-in-python3 , this will help. – Vishnu Upadhyay Sep 04 '15 at 07:07
  • You're making a lot of assumption on how a dictionary in python works, is this founded in anything in particular, and for what version of python, or are you just guessing ? – nos Sep 04 '15 at 07:09
  • Could you please take some pain to explain it? I don't get it. – ashish verma Sep 04 '15 at 07:09
  • @nos I'm not guessing, it's the output which is coming, I'm using Python 2.7.10 – ashish verma Sep 04 '15 at 07:10
  • @ashishverma I'm asking why you do %8, why not %2 ? or anything else ? Why do you assume the existing key should be moved, instead of the new key ? – nos Sep 04 '15 at 07:12
  • @nos ok, you're right, but I want to know, dict prints randomly but it also has a pattern which is decided by the ordering of slots, ie., first it prints slot 1 then slot 2 and so on but if bar is lying in a slot which comes before baz then why bar is not printing first? – ashish verma Sep 04 '15 at 07:16
  • @nos, even if I don't %8 the hash value of `bar` is less than `baz`, which means `bar` is in a slot which comes before `baz` – ashish verma Sep 04 '15 at 07:18
  • Maybe look at the [source](https://github.com/python-git/python/blob/715a6e5035bb21ac49382772076ec4c630d6e960/Objects/dictobject.c#L687). There is stated, that it doesn't always use the key-hash – user2358582 Sep 04 '15 at 07:19
  • Getting deja vu. I think you asked this exact question yesterday and it was closed. – Peter Wood Sep 04 '15 at 07:42

1 Answers1

1

From Python version security release https://mail.python.org/pipermail/python-announce-list/2012-March/009394.html

Hash randomization causes the iteration order of dicts and sets to be unpredictable and differ across Python runs. Python has never guaranteed iteration order of keys in a dict or set, and applications are advised to never rely on it. Historically, dict iteration order has not changed very often across releases and has always remained consistent between successive executions of Python. Thus, some existing applications may be relying on dict or set ordering. Because of this and the fact that many Python applications which don't accept untrusted input are not vulnerable to this attack, in all stable Python releases mentioned here, hash randomization is disabled by default. There are two ways to enable it. The -R commandline option can be passed to the python executable. It can also be enabled by setting an environmental variable pythonhashseed to "random". (Other values are accepted, too; pass -h to python for complete description.)

txsaw1
  • 121
  • 12
Vishnu Upadhyay
  • 4,813
  • 1
  • 11
  • 26
  • I want to know, dict prints randomly but it also has a pattern which is decided by the ordering of slots, ie., first it prints slot 1 then slot 2 and so on but if `bar` is lying in a slot which comes before `baz` then why `bar` is not printing first? – ashish verma Sep 04 '15 at 07:13
  • Python has never guaranteed iteration order of keys in a dict or set, and applications are advised to never rely on it. What i undstand on my side may be at Hash table they put any random function to pick up keys. – Vishnu Upadhyay Sep 04 '15 at 07:21
  • Ashis perhaps you want to use something like ordering dict? – piezol Sep 04 '15 at 07:21