#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
import urllib.parse
import os
import time
import base64
import hashlib
import json

url = "https://wx663ca7ac2632b137.vip.aoyacms.com/plugin/aoya/iot/api.php"#接口地址
key = "d0d3d5b5466cc1ee89eb808de9f5672d"#个人密匙
t = int(time.time())#时间戳
mid = "5b53a2d341d78427feafeb4520bf41eb"#设备密匙
 
class AuthCode(object):
 
    @classmethod
    def encode(cls, string, key, expiry=0):
        """
        编码
        @param string: 带编码字符串
        @param key: 密钥
        @return:加密字符串
        """
        return cls._auth_code(string, 'ENCODE', key, expiry)
 
    @classmethod
    def decode(cls, string, key, expiry=0):
        """
        解码
        @param string: 待解码字符串
        @param key: 密钥
        @return:原始字符串
        """
        return cls._auth_code(string, 'DECODE', key, expiry)
 
    @staticmethod
    def _md5(source_string):
        return hashlib.md5(source_string.encode("latin1")).hexdigest()
 
    @classmethod
    def _auth_code(cls, input_string, operation='DECODE', key='', expiry=3600):
        """
        编码/解码
        @param input_string: 原文或者密文
        @param operation: 操作（加密或者解密，默认是解密）
        @param key: 密钥
        @param expiry: 密文有效期，单位是秒，0 表示永久有效
        @return: 处理后的原文或者经过 base64_encode 处理后的密文
        """
 
        # ----------------------- 获取随机密钥 -----------------------
        #print (cls, input_string, operation, key, expiry)
        rand_key_length = 4
        # 随机密钥长度 取值 0-32
        # 可以令密文无任何规律，即便是原文和密钥完全相同，加密结果也会每次不同，增大破解难度
        # 值越大，密文变动规律越大，密文变化 = 16 的 ckey_length 次方，如果为 0，则不产生随机密钥
 
        key = cls._md5(key)
        #print(key)	
        key_a = cls._md5(key[:16])
        key_b = cls._md5(key[16:])
        #print(key_a)
        #print(key_b)   		
        if rand_key_length:
            if operation == 'DECODE':
                key_c = input_string[:rand_key_length]
            else:
                key_c = cls._md5(str(time.time()))[-rand_key_length:]
        else:
            key_c = ''
        #print(key_c) 
        crypt_key = key_a + cls._md5(key_a + key_c)
        #print(crypt_key) 
        if operation == 'DECODE':
            handled_string = base64.b64decode(input_string[rand_key_length:])
            print('input',input_string[rand_key_length:])			
        else:
            expiration_time = expiry + int(time.time) if expiry else 0
            handled_string = '%010d' % expiration_time + cls._md5(input_string + key_b)[:16] + input_string
            #print(handled_string) 
        rand_key = list()
        for i in range(256):
            rand_key.append(ord(crypt_key[i % len(crypt_key)]))
        #print(handled_string) 
        # ----------------------------------------------------------
        #print(rand_key) 
        box = list(range(256))
        j = 0
        
		
        for i in range(256):
            j = (j + box[i] + rand_key[i]) % 256	
            tmp = box[i]
            box[i] = box[j]		
            box[j] = tmp
            #print(box[i],box[j])           		
            			
        #for i in xrange(len(box)):
        #    print str(box[i]).rjust(5),
        #    if ((i + 1) % 10) == 0:
        #        print ''
 
        result = ''
        a = 0
        j = 0
        for i in range(len(handled_string)):
            a = (a + 1) % 256
            j = (j + box[a]) % 256
            tmp = box[a]
            box[a] = box[j]
            box[j] = tmp
            if operation == 'DECODE':
                result += chr(handled_string[i]^(box[(box[a]+box[j])%256]))
            else:	
                result += chr(ord(handled_string[i])^(box[(box[a]+box[j])%256]))
            #print(ord(handled_string[i])^(box[(box[a]+box[j])%256]))
            
                				
        if operation == 'DECODE':
            if (int(result[:10]) == 0 or (int(result[:10]) - time.time() > 0)) and \
                    (result[10:26] == cls._md5(result[26:] + key_b)[:16]):
                output_string = result[26:]
            else:
                output_string = ''
        else:
            output_string = key_c + base64.b64encode(result.encode('latin1')).decode('latin1')
            #print(base64.b64encode(result.encode('latin1')).decode('latin1')) 
        return output_string
		

info = {
	"act" : "switch" #switch 控制设备开关 getState获取开关状态		
}
json = json.dumps(info)
ciphertext = AuthCode.encode(json, key)
check = hashlib.md5((str(t) + mid + ciphertext).encode("utf-8")).hexdigest()
data =  {
	"ciphertext" :ciphertext,
	"check" : check,
	"mid" : mid,
	"t" : t 
}
#对要发送的数据进行打包

postData = urllib.parse.urlencode(data).encode("utf-8")

#请求体

req = urllib.request.Request(url, postData)

#发起请求

req.add_header( "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36")

response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))
