def pbkdf2_iteration_calculator(hash_algorithm, key_length, target_ms=<NUM_LIT:100>, quiet=False):
if hash_algorithm not in set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(hash_algorithm)<EOL>))<EOL><DEDENT>if not isinstance(key_length, int_types):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(key_length)<EOL>))<EOL><DEDENT>if key_length < <NUM_LIT:1>:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(key_length)<EOL>))<EOL><DEDENT>if not isinstance(target_ms, int_types):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(target_ms)<EOL>))<EOL><DEDENT>if target_ms < <NUM_LIT:1>:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(target_ms)<EOL>))<EOL><DEDENT>if pbkdf2.pure_python:<EOL><INDENT>raise OSError(pretty_message(<EOL>'''<STR_LIT>'''<EOL>))<EOL><DEDENT>iterations = <NUM_LIT><EOL>password = '<STR_LIT>'.encode('<STR_LIT:utf-8>')<EOL>salt = rand_bytes(key_length)<EOL>def _measure():<EOL><INDENT>start = _get_start()<EOL>pbkdf2(hash_algorithm, password, salt, iterations, key_length)<EOL>observed_ms = _get_elapsed(start)<EOL>if not quiet:<EOL><INDENT>print('<STR_LIT>' % (iterations, observed_ms))<EOL><DEDENT>return <NUM_LIT:1.0> / target_ms * observed_ms<EOL><DEDENT>fraction = _measure()<EOL>iterations = int(iterations / fraction / <NUM_LIT>)<EOL>fraction = _measure()<EOL>iterations = iterations / fraction<EOL>round_factor = -<NUM_LIT:3> if iterations < <NUM_LIT> else -<NUM_LIT:4><EOL>result = int(round(iterations, round_factor))<EOL>if result > <NUM_LIT>:<EOL><INDENT>result = (result // <NUM_LIT>) * <NUM_LIT><EOL><DEDENT>return result<EOL>
Runs pbkdf2() twice to determine the approximate number of iterations to
use to hit a desired time per run. Use this on a production machine to
dynamically adjust the number of iterations as high as you can.

:param hash_algorithm:
    The string name of the hash algorithm to use: "md5", "sha1", "sha224",
    "sha256", "sha384", "sha512"

:param key_length:
    The length of the desired key in bytes

:param target_ms:
    The number of milliseconds the derivation should take

:param quiet:
    If no output should be printed as attempts are made

:return:
    An integer number of iterations of PBKDF2 using the specified hash
    that will take at least target_ms