<commit_before># -*- coding: utf-8 -*-
"""
    werkzeug.security
    ~~~~~~~~~~~~~~~~~

    Security related helpers such as secure password hashing tools.

    :copyright: (c) 2013 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""
import os
import hmac
import posixpath
from random import SystemRandom

from werkzeug.exceptions import BadRequest
from werkzeug._compat import xrange, PY2, text_type, izip


SALT_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'


_sys_rng = SystemRandom()
_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep]
                    if sep not in (None, '/'))


def _find_hashlib_algorithms():
    import hashlib
    algos = getattr(hashlib, 'algorithms', None)
    if algos is None:
        algos = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
    rv = {}
    for algo in algos:
        func = getattr(hashlib, algo, None)
        if func is not None:
            rv[algo] = func
    return rv
_hash_funcs = _find_hashlib_algorithms()


def safe_str_cmp(a, b):
    """This function compares strings in somewhat constant time.  This
    requires that the length of at least one string is known in advance.

    Returns `True` if the two strings are equal or `False` if they are not.

    .. versionadded:: 0.7
    """
    if len(a) != len(b):
        return False
    rv = 0
    if isinstance(a, bytes) and isinstance(b, bytes) and not PY2:
        for x, y in izip(a, b):
            rv |= x ^ y<commit_msg>Removed unnessary import and added support for hmac.digest_compare<commit_after># -*- coding: utf-8 -*-
"""
    werkzeug.security
    ~~~~~~~~~~~~~~~~~

    Security related helpers such as secure password hashing tools.

    :copyright: (c) 2013 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""
import os
import hmac
import posixpath
from random import SystemRandom

from werkzeug._compat import xrange, PY2, text_type, izip


SALT_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'


_sys_rng = SystemRandom()
_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep]
                    if sep not in (None, '/'))


def _find_hashlib_algorithms():
    import hashlib
    algos = getattr(hashlib, 'algorithms', None)
    if algos is None:
        algos = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
    rv = {}
    for algo in algos:
        func = getattr(hashlib, algo, None)
        if func is not None:
            rv[algo] = func
    return rv
_hash_funcs = _find_hashlib_algorithms()


_builtin_safe_str_cmp = getattr(hmac, 'digest_compare', None)


def safe_str_cmp(a, b):
    """This function compares strings in somewhat constant time.  This
    requires that the length of at least one string is known in advance.

    Returns `True` if the two strings are equal or `False` if they are not.

    .. versionadded:: 0.7
    """
    if _builtin_safe_str_cmp is not None:
        return _builtin_safe_str_cmp(a, b)
    if len(a) != len(b):
        return False
    rv = 0
    if isinstance(a, bytes) and isinstance(b, bytes) and not PY2:
        for x, y in izip(a, b):
            rv |= x ^ y
{'fraction_non_alphanumeric': 0.1059623107815879, 'fraction_numerical': 0.02100710534445474, 'mean_word_length': 2.9827798277982778, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3908809', 'n_tokens_mistral': 1127, 'n_tokens_neox': 1067, 'n_words': 362}