|  | @@ -0,0 +1,94 @@
 | 
	
		
			
				|  |  | +import os 
 | 
	
		
			
				|  |  | +import hashlib
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class password:
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +    This class is responsible for managing passwords and passwords hashes
 | 
	
		
			
				|  |  | +    generating.
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def __init__(self, target: str, lenght: int = 48) -> None:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This is password initialized. It generate new password hash
 | 
	
		
			
				|  |  | +        from the password. Lenght of the hash could be changed.
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        target: str - Target password
 | 
	
		
			
				|  |  | +        lenght: int - Lenght of the password hash (default: 48)
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        self.__lenght = lenght
 | 
	
		
			
				|  |  | +        self.__target = target
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def lenght(self) -> int:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This return lenght of the hash.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return self.__lenght
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def __salt(self) -> str:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This return random salt with lenght of the hash."
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        return os.urandom(self.lenght).hex()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def separator(self) -> str:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This return separator between salt and hash.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return "."
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def __generate(self, salt: str) -> str:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This generate new hash from the password and salt.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        salt: str - Salt to use when generating
 | 
	
		
			
				|  |  | +        return: str - Password hash generated from given salt
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        salted = salt + self.__target
 | 
	
		
			
				|  |  | +        binary = hashlib.shake_256(salted.encode())
 | 
	
		
			
				|  |  | +        hashed = binary.hexdigest(self.lenght)
 | 
	
		
			
				|  |  | +        full = salt + self.separator + hashed
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return full
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def result(self) -> str:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This generate new hash from the password.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return: str - New password hash with random salt
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return self.__generate(self.__salt)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def validate(self, hashed: str) -> bool:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        This function validate password hash. When passwords match, then
 | 
	
		
			
				|  |  | +        return True, when password from the class not match with given hash,
 | 
	
		
			
				|  |  | +        then return False.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        hashed: str - Password hash to check
 | 
	
		
			
				|  |  | +        return: bool - True when passwords match, False if not
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        position = hashed.find(self.separator)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if position == -1:
 | 
	
		
			
				|  |  | +            return False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        salt = hashed[:position]
 | 
	
		
			
				|  |  | +        full = hashed[position + len(self.separator):]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if len(salt) != len(full):
 | 
	
		
			
				|  |  | +            return False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if len(full) != self.lenght * 2:
 | 
	
		
			
				|  |  | +            return False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return self.__generate(salt) == hashed
 |