1

I am making a python script which hashes a string using an algorithm that the user specifies in input using hashlib. After I hash the string, I want to do the same thing to it, no matter what hash algorithm the user chose. Because of that I wanted to make a function for it, not to repeat code but wouldn't know how to change the built-in hash function based on the input. My code right now looks like this:

current_algorithm = input('Hash algorithm: ')    

if current_algorithm == 'md5':
    hashed = hashlib.md5(word).hexdigest()
    # Execute the same code here
elif current_algorithm == 'sha256':
    hashed = hashlib.sha256(word).hexdigest()
    # Execute the same code here 
elif current_algorithm == 'sha512':
    hashed = hashlib.sha512(word).hexdigest()
    # Execute the same code here

The function hashlib.algorithm(word).hexdigest() has to change depending on which algorithm the user chose. For example, if the user chose sha512, the code would look like this: hashlib.sha512(word).hexdigest(), instead, if the user chose md5, the code would look like this: hashlib.md5(word).hexdigest() and so on. However, the code under these lines is exactly the same and right now I am repeating it 3 times, and possibly more if I will add more algorithms in the future. Therefore how do I make a function that changes algorithm based on user input, so that I do not have to repeat so much code? I was thinking to take advantage of arguments, but wouldn't know how to work around it. This is kind of what I had in mind, but would not work since you can't change built-in methods:

def func(algorithm):
    hashlib.algorithm(word).hexdigest()
    # Execute the same code here

if current_algorithm == 'md5':
    func(current_algorithm)
elif current_algorithm == 'sha256':
    func(current_algorithm)
elif current_algorithm == 'sha512':
    func(current_algorithm)

Then, under every if statement I would call the function with and passing it the user input (containing the hash algorithm) as an argument.

I hope the question is clear and would appreciate any help!

FedeCuci
  • 117
  • 1
  • 1
  • 8
  • 2
    Possible duplicate of [Calling a function of a module by using its name (a string)](https://stackoverflow.com/questions/3061/calling-a-function-of-a-module-by-using-its-name-a-string) (I'm guessing this would be useful for you since you want to call a function name which has the algo in it's name, there for you should be able to stitch something together like `hashlib.'+userinput) – Torxed Feb 03 '19 at 09:00
  • You can pass a function as a value in a dictionary or Pandas data frame, maybe this could help you, test = {"key": func} – shahriar Feb 03 '19 at 09:09
  • @Torxed You are right, that post would have helped me a lot. I am sorry I did not see it. Thanks anyway! – FedeCuci Feb 03 '19 at 09:21

2 Answers2

1

Use getattr:

import hashlib

current_algorithm = input('Hash algorithm: ')    
try:
    hashed = getattr(hashlib, current_algorithm)(word).hexdigest()
except AttributeError:
    print('Invalid algorithm choice')
Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
0

You could also simply extract the common code from the if/else block like this:

current_algorithm = input('Hash algorithm: ')    

if current_algorithm == 'md5':
    hashed = hashlib.md5(word).hexdigest()
elif current_algorithm == 'sha256':
    hashed = hashlib.sha256(word).hexdigest()
elif current_algorithm == 'sha512':
    hashed = hashlib.sha512(word).hexdigest()

# Execute the same code here (using hashed variable)
stellasia
  • 5,372
  • 4
  • 23
  • 43