import sys
from hashlib import blake2b
from hmac import compare_digest
from os import urandom
from typing import Union
import configparser

# ************** Read "config.ini" ********************
config = configparser.ConfigParser()
config.read('config.ini')
hash_size = config['HASH_SIZE']
# ************** END **********************************


class Hash:
    """Generates password hashes, hashes for sessions,
    authenticator ID's, checks passwords hashes.

    Args:
        password (str, required): password.

        uuid (int or str, [str convert to int], required): unique user
              identity.

        salt (Any, required): Salt. additional unique identifier
             (there can be any line: mother's maiden name,
             favorite writer, etc.).

        key (Any, optional): Additional argument. Defaults to None.
            If value of 'key' parameter is 'None' then function
            will generated it.

        hash_password (str, optional): password hash (previously calculated).

    """
    def __init__(self, password: str, uuid: Union[int, str],
                 salt: bytes = None, key: bytes = None,
                 hash_password: str = None):

        if salt is None:
            self.salt = urandom(16)
        else:
            self.salt = salt

        if key is None:
            self.key = urandom(20)
        else:
            self.key = key

        if isinstance(uuid, str):
            self.uuid = int(uuid)
        else:
            self.uuid = uuid

        self.binary_password = password.encode('utf-8')
        self.hash_password = <PASSWORD>
        self.size_password = <PASSWORD>('password')
        self.size_auth_id = hash_size.getint('auth_id')

    def get_salt(self) -> bytes:
        return self.salt

    def get_key(self) -> bytes:
        return self.key

    def password_hash(self) -> str:
        """Generates a password hash.

        Returns:
            str: Returns hash password.
        """
        hash_password = blake2b(self.binary_password,
                                digest_size=self.size_password,
                                key=self.key, salt=self.salt)
        return hash_password.hexdigest()

    def check_password(self) -> bool:
        """Checks password hash and original password.

        Returns:
            bool: True or False
        """
        if self.hash_password is None:
            return False
        else:
            verified_hash_password = self.password_hash()
            return compare_digest(self.hash_password,
                                  verified_hash_password)

    def auth_id(self) -> str:
        """Generates an authenticator ID's for client session
        connection to server.

        Returns:
            str: Returns auth_id
        """
        uuid = self.uuid.to_bytes(self.uuid.bit_length(),
                                  byteorder=sys.byteorder)
        result = blake2b(uuid,
                         digest_size=self.size_auth_id,
                         salt=self.salt)
        return result.hexdigest()

import sys
from hashlib import blake2b
from hmac import compare_digest
from os import urandom
from typing import Union
import configparser

# ************** Read "config.ini" ********************
config = configparser.ConfigParser()
config.read('config.ini')
hash_size = config['HASH_SIZE']
# ************** END **********************************


class Hash:
    """Generates password hashes, hashes for sessions,
    authenticator ID's, checks passwords hashes.

    Args:
        password (str, required): password.

        uuid (int or str, [str convert to int], required): unique user
              identity.

        salt (Any, required): Salt. additional unique identifier
             (there can be any line: mother's maiden name,
             favorite writer, etc.).

        key (Any, optional): Additional argument. Defaults to None.
            If value of 'key' parameter is 'None' then function
            will generated it.

        hash_password (str, optional): password hash (previously calculated).

    """
    def __init__(self, password: str, uuid: Union[int, str],
                 salt: bytes = None, key: bytes = None,
                 hash_password: str = None):

        if salt is None:
            self.salt = urandom(16)
        else:
            self.salt = salt

        if key is None:
            self.key = urandom(20)
        else:
            self.key = key

        if isinstance(uuid, str):
            self.uuid = int(uuid)
        else:
            self.uuid = uuid

        self.binary_password = password.encode('utf-8')
        self.hash_password = <PASSWORD>
        self.size_password = <PASSWORD>('password')
        self.size_auth_id = hash_size.getint('auth_id')

    def get_salt(self) -> bytes:
        return self.salt

    def get_key(self) -> bytes:
        return self.key

    def password_hash(self) -> str:
        """Generates a password hash.

        Returns:
            str: Returns hash password.
        """
        hash_password = blake2b(self.binary_password,
                                digest_size=self.size_password,
                                key=self.key, salt=self.salt)
        return hash_password.hexdigest()

    def check_password(self) -> bool:
        """Checks password hash and original password.

        Returns:
            bool: True or False
        """
        if self.hash_password is None:
            return False
        else:
            verified_hash_password = self.password_hash()
            return compare_digest(self.hash_password,
                                  verified_hash_password)

    def auth_id(self) -> str:
        """Generates an authenticator ID's for client session
        connection to server.

        Returns:
            str: Returns auth_id
        """
        uuid = self.uuid.to_bytes(self.uuid.bit_length(),
                                  byteorder=sys.byteorder)
        result = blake2b(uuid,
                         digest_size=self.size_auth_id,
                         salt=self.salt)
        return result.hexdigest()

# ************** Read "config.ini" ******************** # ************** END ********************************** Generates password hashes, hashes for sessions,     authenticator ID's, checks passwords hashes.      Args:         password (str, required): password.          uuid (int or str, [str convert to int], required): unique user               identity.          salt (Any, required): Salt. additional unique identifier              (there can be any line: mother's maiden name,              favorite writer, etc.).          key (Any, optional): Additional argument. Defaults to None.             If value of 'key' parameter is 'None' then function             will generated it.          hash_password (str, optional): password hash (previously calculated). Generates a password hash.          Returns:             str: Returns hash password. Checks password hash and original password.          Returns:             bool: True or False Generates an authenticator ID's for client session         connection to server.          Returns:             str: Returns auth_id