summaryrefslogtreecommitdiff
path: root/passlib/utils/binary.py
diff options
context:
space:
mode:
Diffstat (limited to 'passlib/utils/binary.py')
-rw-r--r--passlib/utils/binary.py88
1 files changed, 39 insertions, 49 deletions
diff --git a/passlib/utils/binary.py b/passlib/utils/binary.py
index 521b64a..f60ddf2 100644
--- a/passlib/utils/binary.py
+++ b/passlib/utils/binary.py
@@ -5,7 +5,6 @@ passlib.utils.binary - binary data encoding/decoding/manipulation
# imports
#=============================================================================
# core
-from __future__ import absolute_import, division, print_function
from base64 import (
b64encode,
b64decode,
@@ -19,10 +18,9 @@ log = logging.getLogger(__name__)
# pkg
from passlib import exc
from passlib.utils.compat import (
- PY3, bascii_to_str,
- irange, imap, iter_byte_chars, join_byte_values, join_byte_elems,
- nextgetter, suppress_cause,
- u, unicode, unicode_or_bytes_types,
+ bascii_to_str,
+ iter_byte_chars,
+ unicode_or_bytes,
)
from passlib.utils.decor import memoized_property
# from passlib.utils import BASE64_CHARS, HASH64_CHARS
@@ -64,28 +62,28 @@ __all__ = [
#-------------------------------------------------------------
#: standard base64 charmap
-BASE64_CHARS = u("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
+BASE64_CHARS = u"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#: alt base64 charmap -- "." instead of "+"
-AB64_CHARS = u("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./")
+AB64_CHARS = u"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"
#: charmap used by HASH64 encoding.
-HASH64_CHARS = u("./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
+HASH64_CHARS = u"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#: charmap used by BCrypt
-BCRYPT_CHARS = u("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
+BCRYPT_CHARS = u"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#: std base64 chars + padding char
-PADDED_BASE64_CHARS = BASE64_CHARS + u("=")
+PADDED_BASE64_CHARS = BASE64_CHARS + u"="
#: all hex chars
-HEX_CHARS = u("0123456789abcdefABCDEF")
+HEX_CHARS = u"0123456789abcdefABCDEF"
#: upper case hex chars
-UPPER_HEX_CHARS = u("0123456789ABCDEF")
+UPPER_HEX_CHARS = u"0123456789ABCDEF"
#: lower case hex chars
-LOWER_HEX_CHARS = u("0123456789abcdef")
+LOWER_HEX_CHARS = u"0123456789abcdef"
#-------------------------------------------------------------
# byte strings
@@ -93,7 +91,7 @@ LOWER_HEX_CHARS = u("0123456789abcdef")
#: special byte string containing all possible byte values
#: NOTE: for efficiency, this is treated as singleton by some of the code
-ALL_BYTE_VALUES = join_byte_values(irange(256))
+ALL_BYTE_VALUES = bytes(range(256))
#: some string constants we reuse
B_EMPTY = b''
@@ -128,10 +126,10 @@ def compile_byte_translation(mapping, source=None):
assert isinstance(source, bytes) and len(source) == 255
target = list(iter_byte_chars(source))
for k, v in mapping.items():
- if isinstance(k, unicode_or_bytes_types):
+ if isinstance(k, unicode_or_bytes):
k = ord(k)
assert isinstance(k, int) and 0 <= k < 256
- if isinstance(v, unicode):
+ if isinstance(v, str):
v = v.encode("ascii")
assert isinstance(v, bytes) and len(v) == 1
target[k] = v
@@ -152,12 +150,12 @@ def b64s_decode(data):
decode from shortened base64 format which omits padding & whitespace.
uses default ``+/`` altchars.
"""
- if isinstance(data, unicode):
+ if isinstance(data, str):
# needs bytes for replace() call, but want to accept ascii-unicode ala a2b_base64()
try:
data = data.encode("ascii")
except UnicodeEncodeError:
- raise suppress_cause(ValueError("string argument should contain only ASCII characters"))
+ raise ValueError("string argument should contain only ASCII characters") from None
off = len(data) & 3
if off == 0:
pass
@@ -170,7 +168,7 @@ def b64s_decode(data):
try:
return a2b_base64(data)
except _BinAsciiError as err:
- raise suppress_cause(TypeError(err))
+ raise TypeError(err) from None
#=============================================================================
# adapted-base64 encoding
@@ -198,12 +196,12 @@ def ab64_decode(data):
it is primarily used by Passlib's custom pbkdf2 hashes.
"""
- if isinstance(data, unicode):
+ if isinstance(data, str):
# needs bytes for replace() call, but want to accept ascii-unicode ala a2b_base64()
try:
data = data.encode("ascii")
except UnicodeEncodeError:
- raise suppress_cause(ValueError("string argument should contain only ASCII characters"))
+ raise ValueError("string argument should contain only ASCII characters") from None
return b64s_decode(data.replace(b".", b"+"))
#=============================================================================
@@ -233,7 +231,7 @@ def b32decode(source):
padding optional, ignored if present.
"""
# encode & correct for typos
- if isinstance(source, unicode):
+ if isinstance(source, str):
source = source.encode("ascii")
source = source.translate(_b32_translate)
@@ -336,7 +334,7 @@ class Base64Engine(object):
#===================================================================
def __init__(self, charmap, big=False):
# validate charmap, generate encode64/decode64 helper functions.
- if isinstance(charmap, unicode):
+ if isinstance(charmap, str):
charmap = charmap.encode("latin-1")
elif not isinstance(charmap, bytes):
raise exc.ExpectedStringError(charmap, "charmap")
@@ -385,12 +383,9 @@ class Base64Engine(object):
if not isinstance(source, bytes):
raise TypeError("source must be bytes, not %s" % (type(source),))
chunks, tail = divmod(len(source), 3)
- if PY3:
- next_value = nextgetter(iter(source))
- else:
- next_value = nextgetter(ord(elem) for elem in source)
+ next_value = iter(source).__next__
gen = self._encode_bytes(next_value, chunks, tail)
- out = join_byte_elems(imap(self._encode64, gen))
+ out = bytes(map(self._encode64, gen))
##if tail:
## padding = self.padding
## if padding:
@@ -495,9 +490,9 @@ class Base64Engine(object):
if tail == 1:
# only 6 bits left, can't encode a whole byte!
raise ValueError("input string length cannot be == 1 mod 4")
- next_value = nextgetter(imap(self._decode64, source))
+ next_value = map(self._decode64, source).__next__
try:
- return join_byte_values(self._decode_bytes(next_value, chunks, tail))
+ return bytes(self._decode_bytes(next_value, chunks, tail))
except KeyError as err:
raise ValueError("invalid character: %r" % (err.args[0],))
@@ -626,7 +621,7 @@ class Base64Engine(object):
# we have dirty bits - repair the string by decoding last char,
# clearing the padding bits via <mask>, and encoding new char.
- if isinstance(source, unicode):
+ if isinstance(source, str):
cm = self.charmap
last = cm[cm.index(last) & mask]
assert last in padset, "failed to generate valid padding char"
@@ -635,8 +630,7 @@ class Base64Engine(object):
# all chars used by encoding are 7-bit ascii.
last = self._encode64(self._decode64(last) & mask)
assert last in padset, "failed to generate valid padding char"
- if PY3:
- last = bytes([last])
+ last = bytes([last])
return True, source[:-1] + last
def repair_unused(self, source):
@@ -661,19 +655,19 @@ class Base64Engine(object):
"""encode byte string, first transposing source using offset list"""
if not isinstance(source, bytes):
raise TypeError("source must be bytes, not %s" % (type(source),))
- tmp = join_byte_elems(source[off] for off in offsets)
+ tmp = bytes(source[off] for off in offsets)
return self.encode_bytes(tmp)
def decode_transposed_bytes(self, source, offsets):
"""decode byte string, then reverse transposition described by offset list"""
# NOTE: if transposition does not use all bytes of source,
- # the original can't be recovered... and join_byte_elems() will throw
+ # the original can't be recovered... and bytes() will throw
# an error because 1+ values in <buf> will be None.
tmp = self.decode_bytes(source)
buf = [None] * len(offsets)
for off, char in zip(offsets, tmp):
buf[off] = char
- return join_byte_elems(buf)
+ return bytes(buf)
#===================================================================
# integer decoding helpers - mainly used by des_crypt family
@@ -724,9 +718,8 @@ class Base64Engine(object):
raise TypeError("source must be bytes, not %s" % (type(source),))
if len(source) != 1:
raise ValueError("source must be exactly 1 byte")
- if PY3:
- # convert to 8bit int before doing lookup
- source = source[0]
+ # convert to 8bit int before doing lookup
+ source = source[0]
try:
return self._decode64(source)
except KeyError:
@@ -792,13 +785,13 @@ class Base64Engine(object):
pad = -bits % 6
bits += pad
if self.big:
- itr = irange(bits-6, -6, -6)
+ itr = range(bits-6, -6, -6)
# shift to add lsb padding.
value <<= pad
else:
- itr = irange(0, bits, 6)
+ itr = range(0, bits, 6)
# padding is msb, so no change needed.
- return join_byte_elems(imap(self._encode64,
+ return bytes(map(self._encode64,
((value>>off) & 0x3f for off in itr)))
#---------------------------------------------------------------
@@ -809,10 +802,7 @@ class Base64Engine(object):
"""encodes 6-bit integer -> single hash64 character"""
if value < 0 or value > 63:
raise ValueError("value out of range")
- if PY3:
- return self.bytemap[value:value+1]
- else:
- return self._encode64(value)
+ return self.bytemap[value:value+1]
def encode_int12(self, value):
"""encodes 12-bit integer -> 2 char string"""
@@ -821,7 +811,7 @@ class Base64Engine(object):
raw = [value & 0x3f, (value>>6) & 0x3f]
if self.big:
raw = reversed(raw)
- return join_byte_elems(imap(self._encode64, raw))
+ return bytes(map(self._encode64, raw))
def encode_int24(self, value):
"""encodes 24-bit integer -> 4 char string"""
@@ -831,7 +821,7 @@ class Base64Engine(object):
(value>>12) & 0x3f, (value>>18) & 0x3f]
if self.big:
raw = reversed(raw)
- return join_byte_elems(imap(self._encode64, raw))
+ return bytes(map(self._encode64, raw))
def encode_int30(self, value):
"""decode 5 char string -> 30 bit integer"""
@@ -862,7 +852,7 @@ class LazyBase64Engine(Base64Engine):
def _lazy_init(self):
args, kwds = self._lazy_opts
- super(LazyBase64Engine, self).__init__(*args, **kwds)
+ super().__init__(*args, **kwds)
del self._lazy_opts
self.__class__ = Base64Engine