Merge pull request #136 from michele-comitini/speed_triks1
optimizations. Switch to PyCrypto support in pbkdf2 when possible.
This commit is contained in:
@@ -40,15 +40,32 @@
|
||||
:copyright: (c) Copyright 2011 by Armin Ronacher.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import hmac
|
||||
import hashlib
|
||||
#import hmac
|
||||
#import hashlib
|
||||
try:
|
||||
# Use PyCrypto (if available).
|
||||
from Crypto.Hash import HMAC as hmac, SHA as sha1
|
||||
except ImportError:
|
||||
# PyCrypto not available. Use the Python standard library.
|
||||
import hmac
|
||||
try:
|
||||
from hashlib import sha1
|
||||
except ImportError:
|
||||
# hashlib not available. Use the old sha module.
|
||||
import sha as sha1
|
||||
|
||||
from struct import Struct
|
||||
from operator import xor
|
||||
from itertools import izip, starmap
|
||||
|
||||
from collections import deque
|
||||
|
||||
_pack_int = Struct('>I').pack
|
||||
|
||||
try:
|
||||
from Crypto.Util.strxor import strxor
|
||||
except ImportError:
|
||||
def strxor(a, b):
|
||||
return ''.join(chr(xor(ord(x), ord(y))) for x,y in izip(a, b))
|
||||
|
||||
def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None):
|
||||
"""Like :func:`pbkdf2_bin` but returns a hex encoded string."""
|
||||
@@ -61,20 +78,20 @@ def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
|
||||
key of `keylen` bytes. By default SHA-1 is used as hash function,
|
||||
a different hashlib `hashfunc` can be provided.
|
||||
"""
|
||||
hashfunc = hashfunc or hashlib.sha1
|
||||
hashfunc = hashfunc or sha1
|
||||
mac = hmac.new(data, None, hashfunc)
|
||||
def _pseudorandom(x, mac=mac):
|
||||
h = mac.copy()
|
||||
h.update(x)
|
||||
return map(ord, h.digest())
|
||||
buf = []
|
||||
return h.digest()
|
||||
buf = deque()
|
||||
for block in xrange(1, -(-keylen // mac.digest_size) + 1):
|
||||
rv = u = _pseudorandom(salt + _pack_int(block))
|
||||
for i in xrange(iterations - 1):
|
||||
u = _pseudorandom(''.join(map(chr, u)))
|
||||
rv = starmap(xor, izip(rv, u))
|
||||
u = _pseudorandom(u)
|
||||
rv = strxor(rv, u)
|
||||
buf.extend(rv)
|
||||
return ''.join(map(chr, buf))[:keylen]
|
||||
return ''.join(buf)[:keylen]
|
||||
|
||||
|
||||
def test():
|
||||
|
||||
@@ -57,7 +57,7 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1):
|
||||
# if not relative and not from applications:
|
||||
if hasattr(current, 'request') \
|
||||
and level <= 0 \
|
||||
and not name.split('.')[0] in INVALID_MODULES \
|
||||
and not name.partition('.')[0] in INVALID_MODULES \
|
||||
and isinstance(globals, dict):
|
||||
import_tb = None
|
||||
try:
|
||||
|
||||
@@ -24,6 +24,8 @@ import socket
|
||||
import base64
|
||||
import zlib
|
||||
|
||||
_struct_2_long_long = struct.Struct('=QQ')
|
||||
|
||||
python_version = sys.version_info[0]
|
||||
|
||||
if python_version == 2:
|
||||
@@ -31,6 +33,15 @@ if python_version == 2:
|
||||
else:
|
||||
import pickle
|
||||
|
||||
try:
|
||||
from Crypto.Hash import MD5 as md5, \
|
||||
SHA as sha1, \
|
||||
SHA224 as sha224, \
|
||||
SHA256 as sha256, \
|
||||
SHA384 as sha384, \
|
||||
SHA512 as sha512
|
||||
except ImportError:
|
||||
from hashlib import md5, sha1, sha224, sha256, sha384, sha512
|
||||
|
||||
try:
|
||||
from Crypto.Cipher import AES
|
||||
@@ -69,7 +80,7 @@ def compare(a, b):
|
||||
|
||||
def md5_hash(text):
|
||||
""" Generate a md5 hash with the given text """
|
||||
return hashlib.md5(text).hexdigest()
|
||||
return md5(text).hexdigest()
|
||||
|
||||
|
||||
def simple_hash(text, key='', salt='', digest_alg='md5'):
|
||||
@@ -102,17 +113,17 @@ def get_digest(value):
|
||||
return value
|
||||
value = value.lower()
|
||||
if value == "md5":
|
||||
return hashlib.md5
|
||||
return md5
|
||||
elif value == "sha1":
|
||||
return hashlib.sha1
|
||||
return sha1
|
||||
elif value == "sha224":
|
||||
return hashlib.sha224
|
||||
return sha224
|
||||
elif value == "sha256":
|
||||
return hashlib.sha256
|
||||
return sha256
|
||||
elif value == "sha384":
|
||||
return hashlib.sha384
|
||||
return sha384
|
||||
elif value == "sha512":
|
||||
return hashlib.sha512
|
||||
return sha512
|
||||
else:
|
||||
raise ValueError("Invalid digest algorithm: %s" % value)
|
||||
|
||||
@@ -212,7 +223,7 @@ This is not specific to web2py; consider deploying on a different operating syst
|
||||
packed = ''.join(chr(x) for x in ctokens) # python 2
|
||||
else:
|
||||
packed = bytes([]).join(bytes([x]) for x in ctokens) # python 3
|
||||
unpacked_ctokens = struct.unpack('=QQ', packed)
|
||||
unpacked_ctokens = _struct_2_long_long.unpack(packed)
|
||||
return unpacked_ctokens, have_urandom
|
||||
UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom()
|
||||
|
||||
@@ -244,14 +255,12 @@ def web2py_uuid(ctokens=UNPACKED_CTOKENS):
|
||||
"""
|
||||
rand_longs = (random.getrandbits(64), random.getrandbits(64))
|
||||
if HAVE_URANDOM:
|
||||
urand_longs = struct.unpack('=QQ', fast_urandom16())
|
||||
byte_s = struct.pack('=QQ',
|
||||
rand_longs[0] ^ urand_longs[0] ^ ctokens[0],
|
||||
rand_longs[1] ^ urand_longs[1] ^ ctokens[1])
|
||||
urand_longs = _struct_2_long_long.unpack(fast_urandom16())
|
||||
byte_s = _struct_2_long_long.pack(rand_longs[0] ^ urand_longs[0] ^ ctokens[0],
|
||||
rand_longs[1] ^ urand_longs[1] ^ ctokens[1])
|
||||
else:
|
||||
byte_s = struct.pack('=QQ',
|
||||
rand_longs[0] ^ ctokens[0],
|
||||
rand_longs[1] ^ ctokens[1])
|
||||
byte_s = _struct_2_long_long.pack(rand_longs[0] ^ ctokens[0],
|
||||
rand_longs[1] ^ ctokens[1])
|
||||
return str(uuid.UUID(bytes=byte_s, version=4))
|
||||
|
||||
REGEX_IPv4 = re.compile('(\d+)\.(\d+)\.(\d+)\.(\d+)')
|
||||
|
||||
Reference in New Issue
Block a user