Seraphim-Solutions/bettercinema

View on GitHub
misc/md5Crypt.py

Summary

Maintainability
A
1 hr
Test Coverage
from hashlib import md5
from vendor.md5crypt import MAGIC
from vendor.md5crypt import to64


class md5Crypt:
    def __init__(self):
        pass


    def parse_params(self, pw=None, salt=None, magic=None):
        if magic is None:
            magic = MAGIC

        # Take care of the magic string if present
        if salt[:len(magic)] == magic:
            salt = salt[len(magic):]

        # self.salt can have up to 8 characters:
        salt = salt.split('$', 1)[0]

        self.salt = salt[:8].encode('utf-8')
        self.magic = magic.encode('utf-8')
        self.pw = pw.encode('utf-8')


    def ctx(self):
        ctx = self.pw + self.magic + self.salt

        final = md5(self.pw + self.salt + self.pw).digest()
        for pl in range(len(self.pw), 0, -16):
            if pl > 16:
                ctx = ctx + final[:16]
            else:
                ctx = ctx + final[:pl]
        return ctx


    def get_final(self, ctx):
        i = len(self.pw)
        while i:
            if i & 1:
                ctx = ctx + chr(0).encode('utf-8')  # if ($i & 1) { $ctx->add(pack("C", 0)); }
            else:
                ctx = ctx + chr(self.pw[0]).encode('utf-8')
            i = i >> 1
        return md5(ctx).digest()


    def get_ctx1(self):
        for i in range(1000):
            ctx1 = ''.encode('utf-8')
            if i & 1:
                ctx1 = ctx1 + self.pw
            else:
                ctx1 = ctx1 + self.final[:16]

            if i % 3:
                ctx1 = ctx1 + self.salt

            if i % 7:
                ctx1 = ctx1 + self.pw

            if i & 1:
                ctx1 = ctx1 + self.final[:16]
            else:
                ctx1 = ctx1 + self.pw

            self.final = md5(ctx1).digest()


    def md5crypt(self, pw=None, salt=None, magic=None):
        if pw and salt != None:
            self.parse_params(pw=pw, salt=salt, magic=magic)
        else:
            return
        
        ctx = self.ctx()
        self.final = self.get_final(ctx)
        self.get_ctx1()
        
        # Final xform
        passwd = ''

        num = [0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 5]
        x, y, z = 0, 1, 2
        
        for _val in range(5):
            passwd = passwd + to64((int(self.final[num[x]]) << 16) | (int(self.final[num[y]]) << 8) | (int(self.final[num[z]])), 4)
            x, y, z = x + 3, y + 3, z + 3
        
        final_passwd = passwd + to64((int(self.final[11])), 2)
        
        # print(self.magic.decode() + self.salt.decode() + '$' + final_passwd)
        return self.magic.decode() + self.salt.decode() + '$' + final_passwd