2147483136 $ˆl–ßi~”jj"T%õÆY¸Ð”Å£Ì „hO‰¿ËÀÉ?÷"""passlib.utils -- helpers for writing password hashes""" #============================================================================= # imports #============================================================================= from passlib.utils.compat import JYTHON # core from binascii import b2a_base64, a2b_base64, Error as _BinAsciiError from base64 import b64encode, b64decode try: from collections.abc import Sequence from collections.abc import Iterable except ImportError: # py2 compat from collections import Sequence from collections import Iterable from codecs import lookup as _lookup_codec from functools import update_wrapper import itertools import inspect import logging; log = logging.getLogger(__name__) import math import os import sys import random import re if JYTHON: # pragma: no cover -- runtime detection # Jython 2.5.2 lacks stringprep module - # see http://bugs.jython.org/issue1758320 try: import stringprep except ImportError: stringprep = None _stringprep_missing_reason = "not present under Jython" else: import stringprep import time if stringprep: import unicodedata try: import threading except ImportError: # module optional before py37 threading = None import timeit import types from warnings import warn # site # pkg from passlib.utils.binary import ( # [remove these aliases in 2.0] BASE64_CHARS, AB64_CHARS, HASH64_CHARS, BCRYPT_CHARS, Base64Engine, LazyBase64Engine, h64, h64big, bcrypt64, ab64_encode, ab64_decode, b64s_encode, b64s_decode ) from passlib.utils.decor import ( # [remove these aliases in 2.0] deprecated_function, deprecated_method, memoized_property, classproperty, hybrid_method, ) from passlib.exc import ExpectedStringError, ExpectedTypeError from passlib.utils.compat import (add_doc, join_bytes, join_byte_values, join_byte_elems, irange, imap, PY3, u, join_unicode, unicode, byte_elem_value, nextgetter, unicode_or_str, unicode_or_bytes_types, get_method_function, suppress_cause, PYPY) # local __all__ = [ # constants 'JYTHON', 'sys_bits', 'unix_crypt_schemes', 'rounds_cost_values', # unicode helpers 'consteq', 'saslprep', # bytes helpers "xor_bytes", "render_bytes", # encoding helpers 'is_same_codec', 'is_ascii_safe', 'to_bytes', 'to_unicode', 'to_native_str', # host OS 'has_crypt', 'test_crypt', 'safe_crypt', 'tick', # randomness 'rng', 'getrandbytes', 'getrandstr', 'generate_password', # object type / interface tests 'is_crypt_handler', 'is_crypt_context', 'has_rounds_info', 'has_salt_info', ] #============================================================================= # constants #============================================================================= # bitsize of system architecture (32 or 64) sys_bits = int(math.log(sys.maxsize if PY3 else sys.maxint, 2) + 1.5) # list of hashes algs supported by crypt() on at least one OS. # XXX: move to .registry for passlib 2.0? unix_crypt_schemes = [ "sha512_crypt", "sha256_crypt", "sha1_crypt", "bcrypt", "md5_crypt", # "bsd_nthash", "bsdi_crypt", "des_crypt", ] # list of rounds_cost constants rounds_cost_values = [ "linear", "log2" ] # legacy import, will be removed in 1.8 from passlib.exc import MissingBackendError # internal helpers _BEMPTY = b'' _UEMPTY = u("") _USPACE = u(" ") # maximum password size which passlib will allow; see exc.PasswordSizeError MAX_PASSWORD_SIZE = int(os.environ.get("PASSLIB_MAX_PASSWORD_SIZE") or 4096) #============================================================================= # type helpers #============================================================================= class SequenceMixin(object): """ helper which lets r