#! /usr/bin/env python
# vim: tabstop=4

import pyDes, codecs



def desencrypt(key, data, m=pyDes.ECB):
    k = pyDes.des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m)
    return k.encrypt(data) 
    
def desdecrypt(key, data, m=pyDes.ECB):
    k = pyDes.des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m)
    return k.decrypt(data) 

def tripledesencrypt(key, data, m=pyDes.ECB):
    k = pyDes.triple_des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m)
    return k.encrypt(data)
    
def tripledesdecrypt(key, data, m=pyDes.ECB):
    k = pyDes.triple_des(key, pad=None, padmode=pyDes.PAD_NORMAL, mode=m)
    return k.decrypt(data)


def desencrypthex(key, data):
    k = pyDes.des(codecs.decode(key, 'hex'), pad=None, padmode=pyDes.PAD_NORMAL)
    e = k.encrypt(codecs.decode(data, 'hex')) 
    return codecs.encode(e, 'hex')

def tripledesencrypthex(key, data):
    k = pyDes.triple_des(codecs.decode(key, 'hex'), pad=None, padmode=pyDes.PAD_NORMAL)
    e1 = k.encrypt(codecs.decode(data, 'hex'))
    return codecs.encode(e1, 'hex')

def DataNot(data):
    r = ''
    for a in data:
        r = r + chr((~ord(a)) & 0xFF)
    return r
        
def PadCardPhyNo(phyno):
    r = ''
    if len(phyno) < 8:
        pad = "\x80\x00\x00\x00\x00\x00\x00\x00"
        l = 8 - len(phyno)
        r = phyno + pad[:l]
    elif len(phyno) == 8:
        r = phyno
    else:
        r = phyno[:8]
    return r
    
def PadCardPhyNoHex(phyno):
    return codecs.encode(PadCardPhyNo(codecs.decode(phyno, 'hex')), 'hex')
    
def PbocDeliveryKey(factor, key):
    cipherdatanot = ''
    cipherdata = PadCardPhyNo(factor)
    
    print "factor is [%s]" % codecs.encode(cipherdata, 'hex')

    if len(key) == 8: # singledes delivery
        k1 = desencrypt(key, cipherdata)
        return k1
    elif len(key) == 16:
        cipherdatanot = DataNot(cipherdata)
        
        k1 = tripledesencrypt(key, cipherdata)
        k2 = tripledesencrypt(key, cipherdatanot)
        
        return k1 + k2
    else:
        raise ValueError('key length error')
    
def PbocDeliveryKeyHex(factor, key):
    f = codecs.decode(factor, 'hex')
    k = codecs.decode(key, 'hex')
    k1 = PbocDeliveryKey(f, k)
    return codecs.encode(k1, 'hex')
   

def CalcMac3DES(data, initdata, key):
    datalen = len(data)
    k = pyDes.des(key[:8], pad=None, padmode=pyDes.PAD_NORMAL)

    for i in range(datalen / 8):
        m = ""
        for j in range(len(initdata)):
            m = m + chr(ord(initdata[j]) ^ ord(data[i * 8 + j]))

        initdata = m
        x = k.encrypt(initdata)
        initdata = x


    k1 = pyDes.des(key[8:], pad=None, padmode=pyDes.PAD_NORMAL)
    n = k1.decrypt(initdata)
    initdata = k.encrypt(n)
    return initdata
    
def CalcMac3DESHex(data, initdata, key):
    d = codecs.decode(data, 'hex')
    id = codecs.decode(initdata, 'hex')
    k = codecs.decode(key, 'hex')
    k1 = CalcMac3DES(d, id, k)
    return codecs.encode(k1, 'hex')
    
def CalcMacDES(data, initdata, key):
    datalen = len(data)
    k = pyDes.des(key, pad=None, padmode=pyDes.PAD_NORMAL)
    
    for i in range(datalen / 8):
        m = ""
        for j in range(len(initdata)):
            m = m + chr(ord(initdata[j]) ^ ord(data[i * 8 + j]))

        initdata = m
        x = k.encrypt(initdata)
        initdata = x
        
    return initdata
        
def CalcMacDESHex(data, initdata, key):
    d = codecs.decode(data, 'hex')
    id = codecs.decode(initdata, 'hex')
    k = codecs.decode(key, 'hex')
    k1 = CalcMacDES(d, id, k)
    return codecs.encode(k1, 'hex')


def encrypt_m1key(inputkey):
    statickey = codecs.decode('3230303530313331', 'hex')
    key = codecs.decode(inputkey[:16], 'hex')
    outkey = []
    for i in range(8):
        t1 = ord(key[i])
        t2 = ord(statickey[i])
        t = ((~t1) ^ t2) & 0xFF
        outkey.append(chr(t))
    return codecs.encode(''.join(outkey), 'hex')
