<commit_before>"""Python implementation of RNCryptor."""
from __future__ import print_function

import hashlib
import hmac
import sys

from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Protocol import KDF


__all__ = ('RNCryptor', 'decrypt', 'encrypt')
__version__ = '3.1.0'

PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3

if PY2:
    def to_bytes(s):
        if isinstance(s, str):
            return s
        if isinstance(s, unicode):
            return s.encode('utf-8')

    to_str = to_bytes

    def bchr(s):
        return chr(s)

    def bord(s):
        return ord(s)

elif PY3:
    def to_bytes(s):
        if isinstance(s, bytes):
            return s
        if isinstance(s, str):
            return s.encode('utf-8')

    def to_str(s):
        if isinstance(s, bytes):
            return s.decode('utf-8')
        if isinstance(s, str):
            return s

    def bchr(s):
        return bytes([s])

    def bord(s):
        return s


if hasattr(hmac, 'compare_digest'):
    def compare_in_constant_time(left, right):
        return hmac.compare_digest(left, right)
else:
    def compare_in_constant_time(left, right):
        length_left = len(left)
        length_right = len(right)

        result = length_left - length_right
        for i, byte in enumerate(right):
            result |= bord(left[i % length_left]) ^ bord(byte)
        return result == 0


compare_in_constant_time.__doc__ = """\
Compare two values in time proportional to the second one.

Return True if the values are equal, False otherwise.
"""


class RNCryptorError(Exception):
    """Base error for when anything goes wrong with RNCryptor"""
    pass


class DecryptionError(RNCryptorError):
    """Raised when bad data is inputted"""
    pass


class RNCryptor(object):
    """Cryptor for RNCryptor."""

    SALT_SIZE = 8

    def pre_decrypt_data(self, data):
        """Handle data before decryption."""
        data = to_bytes(data)
        return data

    def post_decrypt_data(self, data):
        """Remove useless symbols which appear over padding for AES (PKCS#7)."""
        data = data[:-bord(data[-1])]
        return to_str(data)

    def decrypt(self, data, password):
        """Decrypt `data` using `password`."""
        data = self.pre_decrypt_data(data)
        password = to_<PASSWORD>(password)

        n = len(data)

        version = data[0]
        options = data[1]
        encryption_salt = data[2:10]
        hmac_salt = data[10:18]
        iv = data[18:34]
        cipher_text = data[34:n - 32]<commit_msg>Added __init__ and __str__ to exceptions<commit_after>"""Python implementation of RNCryptor."""
from __future__ import print_function

import hashlib
import hmac
import sys

from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Protocol import KDF


__all__ = ('RNCryptor', 'decrypt', 'encrypt')
__version__ = '3.1.0'

PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3

if PY2:
    def to_bytes(s):
        if isinstance(s, str):
            return s
        if isinstance(s, unicode):
            return s.encode('utf-8')

    to_str = to_bytes

    def bchr(s):
        return chr(s)

    def bord(s):
        return ord(s)

elif PY3:
    def to_bytes(s):
        if isinstance(s, bytes):
            return s
        if isinstance(s, str):
            return s.encode('utf-8')

    def to_str(s):
        if isinstance(s, bytes):
            return s.decode('utf-8')
        if isinstance(s, str):
            return s

    def bchr(s):
        return bytes([s])

    def bord(s):
        return s


if hasattr(hmac, 'compare_digest'):
    def compare_in_constant_time(left, right):
        return hmac.compare_digest(left, right)
else:
    def compare_in_constant_time(left, right):
        length_left = len(left)
        length_right = len(right)

        result = length_left - length_right
        for i, byte in enumerate(right):
            result |= bord(left[i % length_left]) ^ bord(byte)
        return result == 0


compare_in_constant_time.__doc__ = """\
Compare two values in time proportional to the second one.

Return True if the values are equal, False otherwise.
"""


class RNCryptorError(Exception):
    """Base error for when anything goes wrong with RNCryptor."""
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)


class DecryptionError(RNCryptorError):
    """Raised when bad data is inputted."""
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)


class RNCryptor(object):
    """Cryptor for RNCryptor."""

    SALT_SIZE = 8

    def pre_decrypt_data(self, data):
        """Handle data before decryption."""
        data = to_bytes(data)
        return data

    def post_decrypt_data(self, data):
        """Remove useless symbols which appear over padding for AES (PKCS#7)."""
        data = data[:-bord(data[-1])]
        return to_str(data)

    def decrypt(self, data, password):
        """Decrypt `data` using `password`."""
        data = self.pre_decrypt_data(data)
        password = to_bytes(password)

        n = len(data)

        version = data[0]
        options = data[1]
        encryption_salt = data[2:10]
        hmac_salt = data[10:18]
        iv = data[18:34]
        cipher_text = data[34:n - 32]
{'fraction_non_alphanumeric': 0.11206254653760238, 'fraction_numerical': 0.013030528667163067, 'mean_word_length': 2.488961038961039, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, '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': '2584577', 'n_tokens_mistral': 1769, 'n_tokens_neox': 1686, 'n_words': 482}