这是一个python3.X版本的demo,用于对接开关的API接口,可以控制开关的开和关,还有获取开关的状态 数据传输过程使用discuz加解密方法,个人密匙可以自己配置
#!/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"))
|