0

My program calculated only sha256 file hash and I decided to expand the number of possible algorithms. So I started to use getattr() instead direct call. And the hashes have changed.

It took me a while to figure out where the problem was, and here's simple example with string (differences are in ()):

>>> import hashlib
>>> text = 'this is nonsence'.encode()

# unique original
>>> hash1 = hashlib.sha256()
>>> hash1.update(text)
>>> print(hash1.hexdigest())
ea85e601f8e91dbdeeb46b507ff108152575c816089c2d0489313b42461aa502

# pathetic parody
>>> hash2 = getattr(hashlib,'sha256')
>>> hash2().update(text)
>>> print(hash2().hexdigest())
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

# solution
>>> hash3 = getattr(hashlib,'sha256')()
>>> hash3.update(text)
>>> print(hash3.hexdigest())
ea85e601f8e91dbdeeb46b507ff108152575c816089c2d0489313b42461aa502

Can someone please explain me why hash1 not equal hash2() and equal hash3? Did I miss smth? Because for me they are looking the same:

>>> print(hash1)
<sha256 HASH object @ 0x0000027D76700F50>
>>> print(hash2())
<sha256 HASH object @ 0x0000027D76FD7470>
>>> print(hash3)
<sha256 HASH object @ 0x0000027D76D92BF0>

>>> print(type(hash1))
<class '_hashlib.HASH'>
>>>print(type(hash2()))
<class '_hashlib.HASH'>
>>>print(type(hash3))
<class '_hashlib.HASH'>
Sidov
  • 3
  • 3
  • Hint: What's `hashlib.sha256().hexdigest()`? – wjandrea Mar 31 '21 at 23:00
  • 2
    Since you figured out the solution in #3, the answer is contained in the question - you get a different result because in #2 you created two different hash objects, you updated one with the data, and you got the digest from the other (which received no data). – kaya3 Mar 31 '21 at 23:00
  • Given that you figured it out, I'm surprised by your question title - your #1 and #3 are comparing `getattr(obj, 'method')()` and `obj.method()` which give the same result, whereas your #1 and #2 are comparing `getattr(obj, 'method')` (with no call) and `obj.method()` (with the call). You never compared `getattr(obj, 'method')` and `obj.method` without the call. – kaya3 Mar 31 '21 at 23:02
  • Sorry, I tried to formulate question, but that's best I got without make title long as post. Oh, so there were two different objects, looks like it is it. – Sidov Apr 01 '21 at 01:16

1 Answers1

0

In fact, getattr(obj, 'method') and obj.method give the same result, but in case #2, you're using it wrong.

When you call the function hashlib.sha256, it returns a new HASH object, which is what you're dealing with in cases #1 and #3. In case #2 however, hash2 is the function hashlib.sha256, not a HASH object, and that doesn't change when you call it later, meaning:

  • When you do hash2().update(text), the result is thrown away.
  • When you do hash2().hexdigest(), the result is the same as hashlib.sha256().hexdigest(), i.e. the empty hash.

For comparison, case #2 is practically the same as this:

>>> list().append(0)  # Create new list object and append 0
>>> list()  # Create new list object
[]
wjandrea
  • 28,235
  • 9
  • 60
  • 81