# `passlib.utils` - Helper Functions

Warning

This module is primarily used as an internal support module. Its interface has not been finalized yet, and may be changed somewhat between major releases of Passlib, as the internal code is cleaned up and simplified.

This module primarily contains utility functions used internally by Passlib. However, end-user applications may find some of the functions useful, in particular:

> - `consteq()`

> - `saslprep()`

> - `generate_password()`

## Constants

passlib.utils.unix_crypt_schemes

  List of the names of all the hashes in `passlib.hash` which are natively supported by `crypt()` on at least one operating system.

  For all hashes in this list, the expression `passlib.hash.alg.has_backend("os_crypt")` will return `True` if the host OS natively supports the hash. This list is used by `host_context` and `ldap_context` to determine which hashes are supported by the host.

  See also

  Identifiers & Platform Support for a table of which OSes are known to support which hashes.

## Unicode Helpers

passlib.utils.consteq(left, right)

  Check two strings/bytes for equality.

  This is functionally equivalent to `left == right`, but attempts to take constant time relative to the size of the righthand input.

  The purpose of this function is to help prevent timing attacks during digest comparisons: the standard `==` operator aborts after the first mismatched character, causing its runtime to be proportional to the longest prefix shared by the two inputs. If an attacker is able to predict and control one of the two inputs, repeated queries can be leveraged to reveal information about the content of the second argument. To minimize this risk, `consteq()` is designed to take `THETA(len(right))` time, regardless of the contents of the two strings. It is recommended that the attacker-controlled input be passed in as the left-hand value.

  Warning

  This function is not perfect. Various VM-dependant issues (e.g. the VM’s integer object instantiation algorithm, internal unicode representation, etc), may still cause the function’s run time to be affected by the inputs, though in a less predictable manner. To minimize such risks, this function should not be passed `unicode` inputs that might contain non- `ASCII` characters.

  Added in version 1.6.

  Changed in version 1.7: This is an alias for stdlib’s `hmac.compare_digest()` under Python 3.3 and up.

passlib.utils.saslprep(source, param='value')

  Normalizes unicode strings using SASLPrep stringprep profile.

  The SASLPrep profile is defined in RFC 4013. It provides a uniform scheme for normalizing unicode usernames and passwords before performing byte-value sensitive operations such as hashing. Among other things, it normalizes diacritic representations, removes non-printing characters, and forbids invalid characters such as `\n`. Properly internationalized applications should run user passwords through this function before hashing.

  Parameters:

    - source – unicode string to normalize & validate

    - param – Optional noun identifying source parameter in error messages (Defaults to the string `"value"`). This is mainly useful to make the caller’s error messages make more sense contextually.

  Raises:

    - ValueError – if any characters forbidden by the SASLPrep profile are encountered.

    - TypeError – if input is not `unicode`

  Returns:

    normalized unicode string

  Note

  This function is not available under Jython, as the Jython stdlib is missing the `stringprep` module (Jython issue 1758320).

  Added in version 1.6.

## Bytes Helpers

passlib.utils.xor_bytes(left: bytes, right: bytes) → bytes

  Perform bitwise-xor of two byte strings (must be same size)

passlib.utils.render_bytes(source, *args)

  Peform `%` formating using bytes in a uniform manner across Python 2/3.

  This function is motivated by the fact that `bytes` instances do not support `%` or `{}` formatting under Python 3. This function is an attempt to provide a replacement: it converts everything to unicode (decoding bytes instances as `latin-1`), performs the required formatting, then encodes the result to `latin-1`.

  Calling `render_bytes(source, *args)` should function roughly the same as `source % args` under Python 2.

  Todo

  python >= 3.5 added back limited support for bytes %, can revisit when 3.3/3.4 is dropped.

passlib.utils.int_to_bytes(value, count)

  encode integer as single big-endian byte string

passlib.utils.bytes_to_int(value)

  decode byte string as single big-endian integer

## Encoding Helpers

passlib.utils.is_same_codec(left: str, right: str) → bool

  Check if two codec names are aliases for same codec

passlib.utils.is_ascii_codec(codec: str) → bool

  Test if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16)

passlib.utils.is_ascii_safe(source: AnyStr) → bool

  Check if string (bytes or unicode) contains only 7-bit ascii

passlib.utils.to_bytes(source: str | bytes, encoding: str = 'utf-8', param: str = 'value', source_encoding: str | None = None) → bytes

  Helper to normalize input to bytes.

  Parameters:

    - source – Source bytes/unicode to process.

    - encoding – Target encoding (defaults to `"utf-8"`).

    - param – Optional name of variable/noun to reference when raising errors

    - source_encoding – If this is specified, and the source is bytes, the source will be transcoded from source_encoding to encoding (via unicode).

  Raises:

    TypeError – if source is not str or bytes.

  Returns:

    - unicode strings will be encoded using encoding, and returned.

    - if source_encoding is not specified, byte strings will be returned unchanged.

    - if source_encoding is specified, byte strings will be transcoded to encoding.

passlib.utils.to_unicode(source: AnyStr, encoding='utf-8', param='value') → str

  Helper to normalize input to unicode.

  Parameters:

    - source – source bytes/unicode to process.

    - encoding – encoding to use when decoding bytes instances.

    - param – optional name of variable/noun to reference when raising errors.

  Raises:

    TypeError – if source is not str or bytes.

  Returns:

    - returns unicode strings unchanged.

    - returns bytes strings decoded using encoding

passlib.utils.to_native_str(source: AnyStr, encoding='utf-8', param='value') → str

  Take in str or bytes, returns str. leaves str alone, decodes bytes using specified encoding.

  Parameters:

    - source – source unicode or bytes string

    - encoding – encoding to use when encoding unicode or decoding bytes

    - param – optional name of variable/noun to reference when raising errors

## Randomness

passlib.utils.rng

  The random number generator used by Passlib to generate salt strings and other things which don’t require a cryptographically strong source of randomness.

  If `os.urandom()` support is available, this will be an instance of `random.SystemRandom`, otherwise it will use the default python PRNG class, seeded from various sources at startup.

passlib.utils.getrandbytes(rng, count)

  return byte-string containing count number of randomly generated bytes, using specified rng

passlib.utils.getrandstr(rng, charset, count)

  return string containing count number of chars/bytes, whose elements are drawn from specified charset, using specified rng

passlib.utils.generate_password(size=10, charset=<default charset>)

  generate random password using given length & charset

  Parameters:

    - size – size of password.

    - charset –

      optional string specified set of characters to draw from.

      the default charset contains all normal alphanumeric characters, except for the characters `1IiLl0OoS5`, which were omitted due to their visual similarity.

  Returns:

    `str` containing randomly generated password.

  Note

  Using the default character set, on a OS with `SystemRandom` support, this function should generate passwords with 5.7 bits of entropy per character.

  Deprecated since version 1.7: and will be removed in version 2.0, use passlib.pwd.genword() / passlib.pwd.genphrase() instead.

## Interface Tests

passlib.utils.is_crypt_handler(obj)

  check if object follows the PasswordHash API

passlib.utils.is_crypt_context(obj)

  check if object appears to be a `CryptContext` instance

passlib.utils.has_rounds_info(handler)

  check if handler provides the optional rounds information attributes

passlib.utils.has_salt_info(handler)

  check if handler provides the optional salt information attributes

## Submodules

There are also a few sub modules which provide additional utility functions:

- `passlib.utils.handlers` - Framework for writing password hashes
- `passlib.utils.binary` - Binary Helper Functions
- `passlib.utils.des` - DES routines [deprecated]
- `passlib.utils.pbkdf2` - PBKDF2 key derivation algorithm [deprecated]