├── README.md └── Run.py /README.md: -------------------------------------------------------------------------------- 1 | # SunnyRunningPy 2 | A Py 2 Run 3 | 4 | 汉姆上榜大学生吐槽的十大APP :) 5 | 6 | 7 | 感谢[zyc199847](https://github.com/zyc199847)提供的思路 8 | 9 | 本脚本仅供研究,使用者造成的任何后果由使用者自行承担。 10 | ---- 11 | Capture your login token "IMEI" and input to this script. 12 | 13 | 14 | 目前在解决同学们获取IMEI的方案 15 | 已有比较方便的方案是 16 | - Android: 使用Packet Capture这款APP来抓包 17 | - IOS: 断网打开APP会弹出来IMEI... 18 | 19 | -------------------------------------------------------------------------------- /Run.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | import requests 3 | import json 4 | import time 5 | import hashlib 6 | import random 7 | import sys 8 | 9 | 10 | 11 | # Generate table Randomly 12 | alphabet = list('abcdefghijklmnopqrstuvwxyz') 13 | random.shuffle(alphabet) 14 | table = ''.join(alphabet)[:10] 15 | 16 | 17 | def MD5(s): 18 | return hashlib.md5(s.encode()).hexdigest() 19 | 20 | 21 | def encrypt(s): 22 | result = '' 23 | for i in s: 24 | result += table[ord(i) - ord('0')] 25 | # print(result) 26 | return result 27 | 28 | 29 | def Run(IMEI=None): 30 | if IMEI is None: 31 | # Input to IMEI 32 | if(len(sys.argv) > 1): 33 | IMEI = sys.argv[1] 34 | else: 35 | IMEI = str(input("Please Input Your IMEI Arg:")) 36 | if(len(IMEI) != 32): 37 | exit("IMEI Format Error!") 38 | 39 | if (len(sys.argv) > 2 and sys.argv[2].upper() == 'Y'): 40 | pass 41 | else: 42 | print("Your IMEI Code:", IMEI) 43 | Sure = str(input("Sure?(Y/N)")) 44 | if(Sure == 'Y' or Sure == 'y'): 45 | pass 46 | else: 47 | exit("User Aborted.") 48 | 49 | API_ROOT = 'http://client3.aipao.me/api' # client3 for Android 50 | Version = '2.14' 51 | 52 | # Login 53 | TokenRes = requests.get( 54 | API_ROOT + '/%7Btoken%7D/QM_Users/Login_AndroidSchool?IMEICode=' + IMEI) 55 | TokenJson = json.loads(TokenRes.content.decode('utf8', 'ignore')) 56 | 57 | # headers 58 | token = TokenJson['Data']['Token'] 59 | userId = str(TokenJson['Data']['UserId']) 60 | timespan = str(time.time()).replace('.', '')[:13] 61 | auth = 'B' + MD5(MD5(IMEI)) + ':;' + token 62 | nonce = str(random.randint(100000, 10000000)) 63 | sign = MD5(token + nonce + timespan + userId).upper() # sign为大写 64 | 65 | header = {'nonce': nonce, 'timespan': timespan, 66 | 'sign': sign, 'version': Version, 'Accept': None, 'User-Agent': None, 'Accept-Encoding': None, 'Connection': 'Keep-Alive'} 67 | 68 | # Get User Info 69 | 70 | GSurl = API_ROOT + '/' + token + '/QM_Users/GS' 71 | GSres = requests.get(GSurl, headers=header, data={}) 72 | GSjson = json.loads(GSres.content.decode('utf8', 'ignore')) 73 | 74 | Lengths = GSjson['Data']['SchoolRun']['Lengths'] 75 | 76 | print('User Info:',GSjson['Data']['User']['UserID'],GSjson['Data']['User']['NickName'],GSjson['Data']['User']['UserName'],GSjson['Data']['User']['Sex']) 77 | print('Running Info:',GSjson['Data']['SchoolRun']['Sex'],GSjson['Data']['SchoolRun']['SchoolId'],GSjson['Data']['SchoolRun']['SchoolName'],GSjson['Data']['SchoolRun']['MinSpeed'], 78 | GSjson['Data']['SchoolRun']['MaxSpeed'],GSjson['Data']['SchoolRun']['Lengths']) 79 | 80 | # Start Running 81 | SRSurl = API_ROOT + '/' + token + \ 82 | '/QM_Runs/SRS?S1=30.534736&S2=114.367788&S3=' + str(Lengths) 83 | SRSres = requests.get(SRSurl, headers=header, data={}) 84 | SRSjson = json.loads(SRSres.content.decode('utf8', 'ignore')) 85 | 86 | # Generate Runnig Data Randomly 87 | RunTime = str(random.randint(720, 1000)) # seconds 88 | RunDist = str(Lengths + random.randint(0, 3)) # meters 89 | RunStep = str(random.randint(1300, 1600)) # steps 90 | 91 | # Running Sleep 92 | StartT = time.time() 93 | for i in range(int(RunTime)): 94 | time.sleep(1) 95 | print("Current Minutes: %d Running Progress: %.2f%%\r" % 96 | (i / 60, i * 100.0 / int(RunTime)), end='') 97 | print("") 98 | print("Running Seconds:", time.time() - StartT) 99 | 100 | # print(SRSurl) 101 | # print(SRSjson) 102 | 103 | RunId = SRSjson['Data']['RunId'] 104 | 105 | # End Running 106 | EndUrl = API_ROOT + '/' + token + '/QM_Runs/ES?S1=' + RunId + '&S4=' + \ 107 | encrypt(RunTime) + '&S5=' + encrypt(RunDist) + \ 108 | '&S6=&S7=1&S8=' + table + '&S9=' + encrypt(RunStep) 109 | 110 | EndRes = requests.get(EndUrl, headers=header) 111 | EndJson = json.loads(EndRes.content.decode('utf8', 'ignore')) 112 | 113 | print("-----------------------") 114 | print("Time:", RunTime) 115 | print("Distance:", RunDist) 116 | print("Steps:", RunStep) 117 | print("-----------------------") 118 | 119 | if(EndJson['Success']): 120 | print("[+]OK:", EndJson['Data']) 121 | else: 122 | print("[!]Fail:", EndJson['Data']) 123 | 124 | 125 | def main(): 126 | Run() 127 | 128 | 129 | if __name__ == '__main__': 130 | main() 131 | --------------------------------------------------------------------------------