Module spemod

Expand source code
import os, sys, string

# Globals

prepass   = string.ascii_letters * 4

UPPERFLAG   = 0x80000
CAPFLAG     = 0x100000

printable = string.ascii_letters + "'"

base = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(base))

class  spellencrypt():

    ''' Encrypt data passed by the caller '''

    def __init__(self, fname = "spell.txt"):

        self.verbose = 0
        self.bigarr = []
        self.boundsig = []
        self.boundstr = []
        self.boundarr = []
        self.arrlen = 0
        self.hashlen = 2

        cnt = 0
        fpi = open(os.path.join(base, fname), "r")

        # Load to memory
        for aa in fpi:
            aa = aa.strip().lower()
            if len(aa) > 1:
                self.bigarr.append(aa)

                ''' We filter printable at a later stage
                uuu = 0
                for bb in aa:
                    if ord(bb) > 127:
                        #print ("Foreign chars", aa)
                        uuu = 1
                '''
        fpi.close()

        # Quick index
        oldchh = ""
        for aa in self.bigarr:
            cc =  aa[:self.hashlen]
            if  oldchh != cc:
                oldchh = cc
                #print ("Bound:", "'"+ aa +"'")
                self.boundsig.append(cc)
                self.boundarr.append(cnt)
                #self.boundstr.append(aa)
            cnt += 1;
        #self.boundstr.append(aa)

        self.arrlen = len(self.bigarr)

        #for iii in range(len(boundarr)-1):
        #    print (boundarr[iii + 1] - boundarr[iii], boundstr[iii], end="    " )
        #    print

    def     getword(self, www):

        ttt = [0, 0, 0]
        cc =  www[:self.hashlen]
        cnt2 = 0

        '''  # brute
        for dd in range(self.arrlen):
            if self.bigarr[dd] == www:
                ttt = cnt2, dd, dd
                break
        '''

        for bb in self.boundsig:
            if bb == cc:
                cnt3 = self.boundarr[cnt2]
                try:
                    cnt4 = self.boundarr[cnt2+1]
                except:
                    cnt4 = cnt3;
                #print  ("got:", cc, bb, cnt2, self.bigarr[cnt3], "range:", cnt4-cnt3)
                # The dictionary was broken had foreign characters, so we overscanned
                limx = cnt4-cnt3 + 100
                if cnt3 + limx > self.arrlen:
                    limx = self.arrlen - cnt3

                for dd in range(limx):
                    #print (self.bigarr[cnt3 + dd], end=" ")
                    if self.bigarr[(cnt3)+ dd] == www:
                        #print("Found: ",  self.bigarr[cnt3 + dd], cnt2, dd)
                        ttt = cnt2, dd, cnt3 + dd
                        break
                break
            cnt2 += 1

        #if ttt[2] == 0:
        #    print (www, "not found")

        return ttt[2]

    def     revwcoord(self, xxx, yyy):

        ''' Return a word from coordinates '''

        #print ("get:" , xxx, yyy)

        strx = "";
        cnt3 = self.boundarr[xxx]
        strx = self.bigarr[cnt3 + yyy]
        #print("Got: ",  strx)
        return strx

    def     _revword(self, ooo):

        '''  Return a word from ordinal. '''

        strx = "";
        #print("revword", ooo)
        if ooo < len(self.bigarr) and ooo >= 0:
            strx = self.bigarr[ooo]
        else:
            strx = "Indexerror (%d)" % ooo
        return strx

    def     _convert(self, arrx, flag = False):

        ''' Convert input to array of offsets / strings '''

        arr2 = []
        for ww in arrx:
            if len (ww) == 0:
                continue
            if len (ww) > 1:
                nn = self.getword (str.lower(ww))
                if nn != 0:
                    if ww[1] in string.ascii_uppercase:
                        nn |= CAPFLAG
                    elif ww[0] in string.ascii_uppercase:
                        #print("bigg", ww, hex(nn))
                        nn |= UPPERFLAG

                    arr2.append(nn)
                    #print("'" + ww + "'", hex(nn), end = "; ")
                else:
                    arr2.append(ww)
                    #print("'" + ww + "'", hex(nn), end = "; ")
            else:
                if len (ww):
                    arr2.append( ww )
                    #print("'" + ww + "' ", hex(nn), end = "")

        return arr2

    def  enc_dec(self, flag, arrx, passwd):

        ''' Encrypt / Decrypt. Flag is true for encrypt.'''

        strx = "";  cnt = 0; passidx = 0;

        if len(passwd) == 0:
            raise ValueError("Password Cannot be Empty")

        #print(arrx)
        arr2 = self._convert(arrx)
        #print (arr2)

        for ee in arr2:
            #print ("cnt", cnt, "", end="")
            if type(ee) == str:
                if self.verbose > 1:
                    print ("[" + ee + "] ", end="")
                strx +=  ee
            else:
                if flag:
                    if self.verbose > 2:
                        print ("{" + arrx[cnt] + "} ", end="")
                else:
                    if self.verbose > 2:
                        print ("{", arr2[cnt], "} ", end="")

                chh = ord(passwd[passidx])

                #if self.verbose :
                #    print ("chh ", chh, end=" ")

                passidx += 1
                if passidx >= len(passwd):
                    passidx = 0

                ee2 = ee & 0x7ffff

                if self.verbose > 1:
                    print("ee =", ee, " ", end="")

                #                               arrlen
                # ----------|-------------------|---------------------------
                #                         ^org
                #                         ------|------

                #print("adj", ord(chh) * 500, "", end="")

                offs =  chh * 103
                if flag:
                    ee2 += offs
                    if ee2 > self.arrlen:
                        ee2 -= self.arrlen
                else:
                    ee2 -= offs
                    if ee2 < 0:
                        ee2 += self.arrlen

                if self.verbose > 1:
                    print("after_ee =", ee2, "", end="")

                # Reverse conversion
                nstr = self._revword(ee2)
                # Apply flags
                if ee & CAPFLAG:
                    nstr = nstr.upper()
                if ee & UPPERFLAG:
                    nstr = nstr.capitalize()
                if self.verbose:
                    print ("$" + nstr + "$")
                # Add it to results
                strx += nstr
            cnt = cnt + 1
        return strx

    def calcarrlen(arrx):

        ''' calc array length '''
        xlen = 0;
        for ww in arrx:
            xlen += len(ww)
        #print("xlen", xlen);

    #def getlen(self):
    #    if self.verbose > 0:
    #        print("Parsed:", len(self.boundarr), "entries", len(self.bigarr), "total")
    #    return self.arrlen

def pack24(mm):
    xxx = ""
    for aa in range(3):
        xxx += struct.pack("B", mm & 0xff )
        mm = mm >> 8
    return xxx

def upack24(xxx):
    uuu = 0
    for aa in range(3):
        uu = struct.unpack("B", xxx[aa:aa+1] )
        uuu += uu[0] <<  aa * 8
    return uuu

# Primitives.

def xsum(passwd):
    ''' Keep results below 128 by truncation '''
    sss = 0
    for aa in passwd:
        sss += ord(aa)
    return chr(sss & 0xff)

def fwstr(passwd):
    ''' Forward encrypt for pass '''
    passwd2 = passwd + " "
    sss = ""
    for bb in range(0, len(passwd)):
        #print ("c", passwd[bb])
        sss += chr( (ord(passwd2[bb]) + ord(passwd2[bb+1])) & 0xff)
    return sss

def xorstr(passwd):
    ''' xor constant into strings '''
    sss = ""
    for bb in range(0, len(passwd)):
        #print ("c", passwd[bb])
        sss += chr((ord(passwd[bb]) ^ 0x55) & 0xff)
    return sss

def butter(passwd):
    ''' merge the two halfs, similar to the butterfly operatopn '''
    sss = ""; rrr = ""
    for bb in range(0, len(passwd)/2):
        #print ("c", passwd[bb])
        sss += chr((ord(passwd[bb]) + ord(passwd[2*bb]) ) & 0xff)
        rrr += chr((ord(passwd[bb]) + ord(passwd[2*bb]) ) & 0xff)
    return sss + rrr

def bwstr(passwd):
    ''' Backward encrypt for pass '''
    sss = ""
    for bb in range(len(passwd)-1, -1, -1):
        #print ("c", passwd[bb])
        sss += chr( (ord(passwd[bb]) + ord(passwd[bb-1])) & 0xff)
    return sss

# ------------------------------------------------------------------------
# Corrected to handle unicode accidental

ctrlchar = "\n\r| "

def isprint(chh):

    try:
        if ord(chh) > 127:
            return False
        if ord(chh) < 32:
            return False
        if chh in ctrlchar:
            return False
        if chh in string.ascii_letters:
            return True
    except:
        pass

    return False


def hexdump(strx, llen = 16):

    ''' Return a hex dump formatted string '''
    lenx = len(strx)
    outx = ""
    try:
        for aa in range(lenx/16):
            outx += " "
            for bb in range(16):
                try:
                    outx += "%02x " % ord(strx[aa * 16 + bb])
                except:
                    pass
                    out +=  "?? "
                    #outx += "%02x " % strx[aa * 16 + bb]

            outx += " | "
            for cc in range(16):
                chh = strx[aa * 16 + cc]
                if isprint(chh):
                    outx += "%c" % chh
                else:
                    outx += "."
            outx += " | \n"

        # Print remainder on last line
        remn = lenx % 16 ;   divi = lenx / 16
        if remn:
            outx += " "
            for dd in range(remn):
                try:
                    outx += "%02x " % ord(strx[divi * 16 + dd])
                except:
                    outx +=  "?? "
                    pass
                    #outx += "%02x " % int(strx[divi * 16 + dd])

            outx += " " * ((16 - remn) * 3)
            outx += " | "
            for cc in range(remn):
                chh = strx[divi * 16 + cc]
                if isprint(chh):
                    outx += "%c" % chh
                else:
                    outx += "."
            outx += " " * ((16 - remn))
            outx += " | \n"
    except:
        print("Error on hexdump", sys.exc_info())
        #print_exc("hexdump")

    return(outx)


def     genpass(passwd):

    ''' Generate password for enc/dec/ '''

    #print ("'" + prepass + "'" )

    passwd = passwd + prepass + passwd + prepass + passwd

    for aa in range(5):

        passwd = bwstr(passwd)
        passwd = xorstr(passwd)
        passwd = fwstr(passwd)
        passwd = butter(passwd)

    return passwd

# EOF

Functions

def butter(passwd)

merge the two halfs, similar to the butterfly operatopn

Expand source code
def butter(passwd):
    ''' merge the two halfs, similar to the butterfly operatopn '''
    sss = ""; rrr = ""
    for bb in range(0, len(passwd)/2):
        #print ("c", passwd[bb])
        sss += chr((ord(passwd[bb]) + ord(passwd[2*bb]) ) & 0xff)
        rrr += chr((ord(passwd[bb]) + ord(passwd[2*bb]) ) & 0xff)
    return sss + rrr
def bwstr(passwd)

Backward encrypt for pass

Expand source code
def bwstr(passwd):
    ''' Backward encrypt for pass '''
    sss = ""
    for bb in range(len(passwd)-1, -1, -1):
        #print ("c", passwd[bb])
        sss += chr( (ord(passwd[bb]) + ord(passwd[bb-1])) & 0xff)
    return sss
def fwstr(passwd)

Forward encrypt for pass

Expand source code
def fwstr(passwd):
    ''' Forward encrypt for pass '''
    passwd2 = passwd + " "
    sss = ""
    for bb in range(0, len(passwd)):
        #print ("c", passwd[bb])
        sss += chr( (ord(passwd2[bb]) + ord(passwd2[bb+1])) & 0xff)
    return sss
def genpass(passwd)

Generate password for enc/dec/

Expand source code
def     genpass(passwd):

    ''' Generate password for enc/dec/ '''

    #print ("'" + prepass + "'" )

    passwd = passwd + prepass + passwd + prepass + passwd

    for aa in range(5):

        passwd = bwstr(passwd)
        passwd = xorstr(passwd)
        passwd = fwstr(passwd)
        passwd = butter(passwd)

    return passwd
def hexdump(strx, llen=16)

Return a hex dump formatted string

Expand source code
def hexdump(strx, llen = 16):

    ''' Return a hex dump formatted string '''
    lenx = len(strx)
    outx = ""
    try:
        for aa in range(lenx/16):
            outx += " "
            for bb in range(16):
                try:
                    outx += "%02x " % ord(strx[aa * 16 + bb])
                except:
                    pass
                    out +=  "?? "
                    #outx += "%02x " % strx[aa * 16 + bb]

            outx += " | "
            for cc in range(16):
                chh = strx[aa * 16 + cc]
                if isprint(chh):
                    outx += "%c" % chh
                else:
                    outx += "."
            outx += " | \n"

        # Print remainder on last line
        remn = lenx % 16 ;   divi = lenx / 16
        if remn:
            outx += " "
            for dd in range(remn):
                try:
                    outx += "%02x " % ord(strx[divi * 16 + dd])
                except:
                    outx +=  "?? "
                    pass
                    #outx += "%02x " % int(strx[divi * 16 + dd])

            outx += " " * ((16 - remn) * 3)
            outx += " | "
            for cc in range(remn):
                chh = strx[divi * 16 + cc]
                if isprint(chh):
                    outx += "%c" % chh
                else:
                    outx += "."
            outx += " " * ((16 - remn))
            outx += " | \n"
    except:
        print("Error on hexdump", sys.exc_info())
        #print_exc("hexdump")

    return(outx)
def isprint(chh)
Expand source code
def isprint(chh):

    try:
        if ord(chh) > 127:
            return False
        if ord(chh) < 32:
            return False
        if chh in ctrlchar:
            return False
        if chh in string.ascii_letters:
            return True
    except:
        pass

    return False
def pack24(mm)
Expand source code
def pack24(mm):
    xxx = ""
    for aa in range(3):
        xxx += struct.pack("B", mm & 0xff )
        mm = mm >> 8
    return xxx
def upack24(xxx)
Expand source code
def upack24(xxx):
    uuu = 0
    for aa in range(3):
        uu = struct.unpack("B", xxx[aa:aa+1] )
        uuu += uu[0] <<  aa * 8
    return uuu
def xorstr(passwd)

xor constant into strings

Expand source code
def xorstr(passwd):
    ''' xor constant into strings '''
    sss = ""
    for bb in range(0, len(passwd)):
        #print ("c", passwd[bb])
        sss += chr((ord(passwd[bb]) ^ 0x55) & 0xff)
    return sss
def xsum(passwd)

Keep results below 128 by truncation

Expand source code
def xsum(passwd):
    ''' Keep results below 128 by truncation '''
    sss = 0
    for aa in passwd:
        sss += ord(aa)
    return chr(sss & 0xff)

Classes

class spellencrypt (fname='spell.txt')

Encrypt data passed by the caller

Expand source code
class  spellencrypt():

    ''' Encrypt data passed by the caller '''

    def __init__(self, fname = "spell.txt"):

        self.verbose = 0
        self.bigarr = []
        self.boundsig = []
        self.boundstr = []
        self.boundarr = []
        self.arrlen = 0
        self.hashlen = 2

        cnt = 0
        fpi = open(os.path.join(base, fname), "r")

        # Load to memory
        for aa in fpi:
            aa = aa.strip().lower()
            if len(aa) > 1:
                self.bigarr.append(aa)

                ''' We filter printable at a later stage
                uuu = 0
                for bb in aa:
                    if ord(bb) > 127:
                        #print ("Foreign chars", aa)
                        uuu = 1
                '''
        fpi.close()

        # Quick index
        oldchh = ""
        for aa in self.bigarr:
            cc =  aa[:self.hashlen]
            if  oldchh != cc:
                oldchh = cc
                #print ("Bound:", "'"+ aa +"'")
                self.boundsig.append(cc)
                self.boundarr.append(cnt)
                #self.boundstr.append(aa)
            cnt += 1;
        #self.boundstr.append(aa)

        self.arrlen = len(self.bigarr)

        #for iii in range(len(boundarr)-1):
        #    print (boundarr[iii + 1] - boundarr[iii], boundstr[iii], end="    " )
        #    print

    def     getword(self, www):

        ttt = [0, 0, 0]
        cc =  www[:self.hashlen]
        cnt2 = 0

        '''  # brute
        for dd in range(self.arrlen):
            if self.bigarr[dd] == www:
                ttt = cnt2, dd, dd
                break
        '''

        for bb in self.boundsig:
            if bb == cc:
                cnt3 = self.boundarr[cnt2]
                try:
                    cnt4 = self.boundarr[cnt2+1]
                except:
                    cnt4 = cnt3;
                #print  ("got:", cc, bb, cnt2, self.bigarr[cnt3], "range:", cnt4-cnt3)
                # The dictionary was broken had foreign characters, so we overscanned
                limx = cnt4-cnt3 + 100
                if cnt3 + limx > self.arrlen:
                    limx = self.arrlen - cnt3

                for dd in range(limx):
                    #print (self.bigarr[cnt3 + dd], end=" ")
                    if self.bigarr[(cnt3)+ dd] == www:
                        #print("Found: ",  self.bigarr[cnt3 + dd], cnt2, dd)
                        ttt = cnt2, dd, cnt3 + dd
                        break
                break
            cnt2 += 1

        #if ttt[2] == 0:
        #    print (www, "not found")

        return ttt[2]

    def     revwcoord(self, xxx, yyy):

        ''' Return a word from coordinates '''

        #print ("get:" , xxx, yyy)

        strx = "";
        cnt3 = self.boundarr[xxx]
        strx = self.bigarr[cnt3 + yyy]
        #print("Got: ",  strx)
        return strx

    def     _revword(self, ooo):

        '''  Return a word from ordinal. '''

        strx = "";
        #print("revword", ooo)
        if ooo < len(self.bigarr) and ooo >= 0:
            strx = self.bigarr[ooo]
        else:
            strx = "Indexerror (%d)" % ooo
        return strx

    def     _convert(self, arrx, flag = False):

        ''' Convert input to array of offsets / strings '''

        arr2 = []
        for ww in arrx:
            if len (ww) == 0:
                continue
            if len (ww) > 1:
                nn = self.getword (str.lower(ww))
                if nn != 0:
                    if ww[1] in string.ascii_uppercase:
                        nn |= CAPFLAG
                    elif ww[0] in string.ascii_uppercase:
                        #print("bigg", ww, hex(nn))
                        nn |= UPPERFLAG

                    arr2.append(nn)
                    #print("'" + ww + "'", hex(nn), end = "; ")
                else:
                    arr2.append(ww)
                    #print("'" + ww + "'", hex(nn), end = "; ")
            else:
                if len (ww):
                    arr2.append( ww )
                    #print("'" + ww + "' ", hex(nn), end = "")

        return arr2

    def  enc_dec(self, flag, arrx, passwd):

        ''' Encrypt / Decrypt. Flag is true for encrypt.'''

        strx = "";  cnt = 0; passidx = 0;

        if len(passwd) == 0:
            raise ValueError("Password Cannot be Empty")

        #print(arrx)
        arr2 = self._convert(arrx)
        #print (arr2)

        for ee in arr2:
            #print ("cnt", cnt, "", end="")
            if type(ee) == str:
                if self.verbose > 1:
                    print ("[" + ee + "] ", end="")
                strx +=  ee
            else:
                if flag:
                    if self.verbose > 2:
                        print ("{" + arrx[cnt] + "} ", end="")
                else:
                    if self.verbose > 2:
                        print ("{", arr2[cnt], "} ", end="")

                chh = ord(passwd[passidx])

                #if self.verbose :
                #    print ("chh ", chh, end=" ")

                passidx += 1
                if passidx >= len(passwd):
                    passidx = 0

                ee2 = ee & 0x7ffff

                if self.verbose > 1:
                    print("ee =", ee, " ", end="")

                #                               arrlen
                # ----------|-------------------|---------------------------
                #                         ^org
                #                         ------|------

                #print("adj", ord(chh) * 500, "", end="")

                offs =  chh * 103
                if flag:
                    ee2 += offs
                    if ee2 > self.arrlen:
                        ee2 -= self.arrlen
                else:
                    ee2 -= offs
                    if ee2 < 0:
                        ee2 += self.arrlen

                if self.verbose > 1:
                    print("after_ee =", ee2, "", end="")

                # Reverse conversion
                nstr = self._revword(ee2)
                # Apply flags
                if ee & CAPFLAG:
                    nstr = nstr.upper()
                if ee & UPPERFLAG:
                    nstr = nstr.capitalize()
                if self.verbose:
                    print ("$" + nstr + "$")
                # Add it to results
                strx += nstr
            cnt = cnt + 1
        return strx

    def calcarrlen(arrx):

        ''' calc array length '''
        xlen = 0;
        for ww in arrx:
            xlen += len(ww)
        #print("xlen", xlen);

    #def getlen(self):
    #    if self.verbose > 0:
    #        print("Parsed:", len(self.boundarr), "entries", len(self.bigarr), "total")
    #    return self.arrlen

Methods

def calcarrlen(arrx)

calc array length

Expand source code
def calcarrlen(arrx):

    ''' calc array length '''
    xlen = 0;
    for ww in arrx:
        xlen += len(ww)
    #print("xlen", xlen);
def enc_dec(self, flag, arrx, passwd)

Encrypt / Decrypt. Flag is true for encrypt.

Expand source code
def  enc_dec(self, flag, arrx, passwd):

    ''' Encrypt / Decrypt. Flag is true for encrypt.'''

    strx = "";  cnt = 0; passidx = 0;

    if len(passwd) == 0:
        raise ValueError("Password Cannot be Empty")

    #print(arrx)
    arr2 = self._convert(arrx)
    #print (arr2)

    for ee in arr2:
        #print ("cnt", cnt, "", end="")
        if type(ee) == str:
            if self.verbose > 1:
                print ("[" + ee + "] ", end="")
            strx +=  ee
        else:
            if flag:
                if self.verbose > 2:
                    print ("{" + arrx[cnt] + "} ", end="")
            else:
                if self.verbose > 2:
                    print ("{", arr2[cnt], "} ", end="")

            chh = ord(passwd[passidx])

            #if self.verbose :
            #    print ("chh ", chh, end=" ")

            passidx += 1
            if passidx >= len(passwd):
                passidx = 0

            ee2 = ee & 0x7ffff

            if self.verbose > 1:
                print("ee =", ee, " ", end="")

            #                               arrlen
            # ----------|-------------------|---------------------------
            #                         ^org
            #                         ------|------

            #print("adj", ord(chh) * 500, "", end="")

            offs =  chh * 103
            if flag:
                ee2 += offs
                if ee2 > self.arrlen:
                    ee2 -= self.arrlen
            else:
                ee2 -= offs
                if ee2 < 0:
                    ee2 += self.arrlen

            if self.verbose > 1:
                print("after_ee =", ee2, "", end="")

            # Reverse conversion
            nstr = self._revword(ee2)
            # Apply flags
            if ee & CAPFLAG:
                nstr = nstr.upper()
            if ee & UPPERFLAG:
                nstr = nstr.capitalize()
            if self.verbose:
                print ("$" + nstr + "$")
            # Add it to results
            strx += nstr
        cnt = cnt + 1
    return strx
def getword(self, www)
Expand source code
def     getword(self, www):

    ttt = [0, 0, 0]
    cc =  www[:self.hashlen]
    cnt2 = 0

    '''  # brute
    for dd in range(self.arrlen):
        if self.bigarr[dd] == www:
            ttt = cnt2, dd, dd
            break
    '''

    for bb in self.boundsig:
        if bb == cc:
            cnt3 = self.boundarr[cnt2]
            try:
                cnt4 = self.boundarr[cnt2+1]
            except:
                cnt4 = cnt3;
            #print  ("got:", cc, bb, cnt2, self.bigarr[cnt3], "range:", cnt4-cnt3)
            # The dictionary was broken had foreign characters, so we overscanned
            limx = cnt4-cnt3 + 100
            if cnt3 + limx > self.arrlen:
                limx = self.arrlen - cnt3

            for dd in range(limx):
                #print (self.bigarr[cnt3 + dd], end=" ")
                if self.bigarr[(cnt3)+ dd] == www:
                    #print("Found: ",  self.bigarr[cnt3 + dd], cnt2, dd)
                    ttt = cnt2, dd, cnt3 + dd
                    break
            break
        cnt2 += 1

    #if ttt[2] == 0:
    #    print (www, "not found")

    return ttt[2]
def revwcoord(self, xxx, yyy)

Return a word from coordinates

Expand source code
def     revwcoord(self, xxx, yyy):

    ''' Return a word from coordinates '''

    #print ("get:" , xxx, yyy)

    strx = "";
    cnt3 = self.boundarr[xxx]
    strx = self.bigarr[cnt3 + yyy]
    #print("Got: ",  strx)
    return strx