#!/usr/bin/python

# tzrc4.py
#       --copyright--                   Copyright 2007 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       February 24, 2005       bar
#       November 18, 2007       bar     turn on doxygen
#       November 27, 2007       bar     insert boilerplate copyright
#       May 17, 2008            bar     email adr
#       May 27, 2012            bar     doxygen namespace
#       --eodstamps--
##      \file
#       \namespace              tzpython.tzrc4
#
#
#       RC4 encryption
#
#       Command line:
#
#           input_file key output_file
#
#

import  string
from    types                   import  ListType, TupleType


__ALL__ = [
            'tz_rc4',
          ]




class tz_rc4 :
    """
        RC4 / ARC4 encryption.
    """


    def __init__(me, key = "") :

        me.x    = 0
        me.y    = 0

        me.t    = range(256)

        if  len(key) == 0 :
            key = "\0"

        ki      = 0
        j       = 0
        for i in range(0, 256) :
            j          = (ord(key[ki]) + me.t[i] + j) & 0xff
            me.t[i], me.t[j] = me.t[j], me.t[i]
            ki        += 1
            if  ki >= len(key) :
                ki  = 0
            pass

        pass


    def crypt(me, data_str) :

        if  isinstance(data_str, ListType) or isinstance(data_str, TupleType) :
            data_str = string.join(map(lambda x : str(x), data_str), "")

        r   = []
        for i in range(0, len(data_str)) :
            me.x        = (me.x + 1) & 0xff

            b           = me.t[me.x]
            me.y        = (me.y + b) & 0xff;
            bb          = me.t[me.y];
            me.t[me.x]  = bb
            me.t[me.y]  = b;

            r.append(chr(ord(data_str[i]) ^ me.t[(b + bb) & 0xff]))

        return(string.join(r, ""))




#
#
#   Test code.
#
#
if __name__ == '__main__' :
    import  sys

    import  TZCommandLineAtFile

    del(sys.argv[0])

    TZCommandLineAtFile.expand_at_sign_command_line_files(sys.argv)

    if  len(sys.argv) != 3 :
        print "Tell me input file, key, and output file names!"
        sys.exit(101)

    fin = sys.argv[0]
    key = sys.argv[1]
    fon = sys.argv[2]

    rc4 = tz_rc4(key)

    d   = open(fin, "rb").read()
    d   = rc4.crypt(d)
    open(fon, "wb").write(d)


#
#
#
# eof
