# -*- coding: utf-8 -*-
"""Password hashing functions and constants for the mudpy engine."""
-# Copyright (c) 2004-2012 Jeremy Stanley <fungi@yuggoth.org>. Permission
+# Copyright (c) 2004-2013 Jeremy Stanley <fungi@yuggoth.org>. Permission
# to use, copy, modify, and distribute this software is granted under
# terms provided in the LICENSE file distributed with this software.
between 0 and 255 into a packed sequence akin to a C-style string.
"""
import struct
- # this will need to be declared as b"" during 2to3 migration
- packed = ""
+ packed = b""
for number in numbers:
number = int(number)
assert 0 <= number <= 255
- # need to use b"B" during 2to3 migration
packed += struct.pack("B", number)
return packed
import base64
return base64.b64encode(
byte_sequence,
- "./".encode("ascii")
- ).rstrip("=")
+ b"./"
+ ).decode("ascii").rstrip("=")
def _generate_salt(salt_len=2):
import re
assert re.match("^[0-9a-f]{32}$",
legacy_hash), "Not a valid MD5 hexdigest"
- # this needs to be declared as b"" in 2to3
- collapsed = ""
+ collapsed = b""
for i in range(16):
# this needs to become a byte() call in 2to3
- collapsed += chr(int(legacy_hash[2 * i:2 * i + 2], 16))
+ collapsed += bytes(legacy_hash[2 * i:2 * i + 2].decode("ascii"))
return "%s%s%s%s%s%s%s%s" % (
sep,
MD5,
# iterate the hashing algorithm over its own digest the specified
# number of times
for i in range(2 ** rounds):
- hashed = algorithms[algorithm](hashed).digest()
+ hashed = algorithms[algorithm](hashed.encode("utf-8")).digest()
+ # TODO: remove this exception trap after the switch to py2k
+ try:
+ hashed = "".join(format(x, "02x") for x in bytes(hashed))
+ except ValueError:
+ hashed = "".join(format(ord(x), "02x") for x in bytes(hashed))
# concatenate the output fields, coercing into text form as needed
return "%s%s%s%s%s%s%s%s" % (
- sep, algorithm, sep, rounds, sep, salt, sep, _bytes_to_text(hashed)
+ sep, algorithm, sep, rounds, sep, salt, sep,
+ _bytes_to_text(hashed.encode("ascii"))
)