You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
7.1 KiB
199 lines
7.1 KiB
import binascii
|
|
import json
|
|
import random
|
|
import time
|
|
|
|
from utils.tool import download_q
|
|
from xhs.xhs_aes import aes_encrypt
|
|
from xhs.xhs_des import MD5, des_encrypt, logical_right_shift
|
|
import base64
|
|
"""
|
|
修补xhs xs-xt 算法为 aes
|
|
"""
|
|
|
|
def get_xs(a1, url, data, x_t):
|
|
"""
|
|
获得 {"x-s":"", "x-t": ""}
|
|
:param a1:
|
|
:param url:
|
|
:param data:
|
|
:param x_t:
|
|
:return:
|
|
"""
|
|
key = [187050025, 472920585, 186915882, 876157969, 255199502, 806945584, 220596020, 958210835, 757275681, 940378667,
|
|
489892883, 705504304, 354103316, 688857884, 890312192, 219096591, 622400037, 254088489, 907618332, 52759587,
|
|
907877143, 53870614, 839463457, 389417746, 975774727, 372382245, 437136414, 909246726, 168694017, 473575703,
|
|
52697872, 1010440969]
|
|
|
|
# 7.19 改
|
|
key = [52833590, 1010372866, 188091914, 406398501, 255201040, 957421848, 741478954, 958217745, 758320394, 990653224,
|
|
958072630, 722273561, 890968096, 185282339, 890768915, 254222393, 890835209, 86457382, 907354431, 120004616,
|
|
906834724, 120984878, 841809977, 370543655, 405617431, 909250592, 439235128, 875174166, 187044111, 742001189,
|
|
184950816, 1010310941]
|
|
|
|
def get_enviroment(api="/api/sns/web/v1/feed", data="{}"):
|
|
url = f"url={api}"
|
|
info = url + data
|
|
info = MD5(info)
|
|
return info
|
|
|
|
x1 = get_enviroment(url, data)
|
|
x2 = "0|0|0|1|0|0|1|0|0|0|1|0|0|0|0"
|
|
x3 = a1
|
|
x4 = x_t
|
|
info = f"x1={x1};x2={x2};x3={x3};x4={x4};"
|
|
|
|
key_46_base64 = base64.b64encode(info.encode('utf-8')).decode('utf-8')
|
|
# base64 转为十进制数
|
|
array = [ord(i) for i in key_46_base64]
|
|
|
|
# 对上述数组进行位移操作 初始化明文 每四个数为一组进行计算
|
|
# payload = des_encrypt(key, array)[0]
|
|
payload = aes_encrypt(array)
|
|
|
|
_base_data = {
|
|
"signSvn": "53",
|
|
"signType": "x2",
|
|
"appId": "xhs-pc-web",
|
|
"signVersion": "1",
|
|
"payload": payload
|
|
}
|
|
data = json.dumps(_base_data, ensure_ascii=False, separators=(',', ':'))
|
|
x_s = base64.b64encode(data.encode("utf-8")).decode("utf-8")
|
|
|
|
return {"x-s": "XYW_" + x_s, "x-t": x4}
|
|
|
|
|
|
def decrypt_info(captcha_info):
|
|
"""
|
|
对于验证码的captchaInfo进行解密
|
|
:param captcha_info:
|
|
:return:
|
|
"""
|
|
d1_h = base64.b64decode(captcha_info).hex()
|
|
hex_string = [int(d1_h[i:i + 2], 16) for i in range(0, len(d1_h), 2)]
|
|
|
|
key = [302776838, 875694381, 453784583, 103810086, 571285557, 371853838, 805843717, 657858610, 909711421, 117571586,
|
|
806950164, 52892707, 890572860, 184812328, 605753650, 151859252, 890381338, 556605977, 221318145, 688470832,
|
|
20581922, 940376595, 220597508, 706218773, 707144202, 940115729, 153491459, 892344601, 171182610, 337259779,
|
|
36577297, 271782150]
|
|
|
|
payload = des_encrypt(key, hex_string)[-1]
|
|
|
|
return payload
|
|
|
|
|
|
def encrypt_info(plain_text, _type="mouseEnd"):
|
|
"""
|
|
提交参数进行加密:
|
|
mouseEnd: 最终滑动的距离 比例 286/360
|
|
time: 开始到结束的时间差 毫秒级
|
|
track: 轨迹:[x,y,时间差]
|
|
width: 宽度 固定 286
|
|
:param plain_text:
|
|
:param _type:
|
|
:return:
|
|
"""
|
|
key_list = {
|
|
"mouseEnd": [187040774,941175553,188094512,672732199,87169561,957943856,758133532,957159952,756225326,588057094,890963239,185401634,889790517,185020707,874067993,103227439,874058250,119748888,906756366,119942921,571280678,104203531,304941601,372245811,439101969,808593969,170278418,876218908,186782722,1010306836,187048244,942146861],
|
|
"time": [151392289,942357812,20069652,739772683,18094115,959001623,789850125,17376056,624043796,51713567,606673961,990187014,1007232771,571224112,286990908,36584204,872954931,235544848,18625028,103158589,35458076,86060551,908336391,19927066,572793385,842413842,170468621,907553325,422194994,806880270,170526239,738861861],
|
|
"track": [187578120,538642213,135659559,941298489,221391896,489174819,724704537,688193565,605502240,723068432,890766372,453786172,691602974,50791978,874190097,656489730,337328660,120465962,856495123,218504222,805646351,104007424,373040900,371339527,170658349,622200847,539437315,876100658,455352379,975704860,456002850,940583190],
|
|
"width": [187040774,941175553,188094512,672732199,87169561,957943856,758133532,957159952,756225326,588057094,890963239,185401634,889790517,185020707,874067993,103227439,874058250,119748888,906756366,119942921,571280678,104203531,304941601,372245811,439101969,808593969,170278418,876218908,186782722,1010306836,187048244,942146861]
|
|
}
|
|
key = key_list[_type]
|
|
padding = 8 - len(plain_text) % 8
|
|
|
|
plain_text = [ord(i) for i in plain_text]
|
|
for c in range(padding): # 补位
|
|
plain_text.append(padding)
|
|
|
|
array1_hex2 = des_encrypt(key, plain_text)[0]
|
|
byte_data = binascii.unhexlify(array1_hex2)
|
|
base64_data = base64.b64encode(byte_data).decode("utf-8")
|
|
return base64_data
|
|
|
|
|
|
def get_a1(platform_type="Mac OS"):
|
|
"""
|
|
获取cookie a1、webId 平台类型可能会涉及风控
|
|
:param platform_type:
|
|
:return:
|
|
"""
|
|
|
|
def genRandomString(length):
|
|
char_list = "abcdefghijklmnopqrstuvwxyz1234567890"
|
|
return ''.join(random.sample(char_list, length))
|
|
|
|
def crc32(data):
|
|
table = []
|
|
for num in range(256):
|
|
temp = num
|
|
for _ in range(8):
|
|
temp = (logical_right_shift(temp, 1)) ^ 0XEDB88320 if temp & 1 else logical_right_shift(temp, 1)
|
|
table.append(temp)
|
|
i = -1
|
|
for a in range(len(data)):
|
|
i = logical_right_shift(i, 8) ^ table[255 & (i ^ ord(data[a]))]
|
|
return logical_right_shift((-1 ^ i), 0)
|
|
|
|
def getPlatformCode(t):
|
|
# 根据不同系统返回结果
|
|
if t == "Android":
|
|
return "2"
|
|
elif t == "iOS":
|
|
return "1"
|
|
elif t == "Mac OS":
|
|
return "3"
|
|
elif t == "Linux":
|
|
return "4"
|
|
# elif t == "Windows":
|
|
# return "0"
|
|
else:
|
|
return "5"
|
|
|
|
LOCAL_ID_SECRET_VERSION = "0"
|
|
o = str(hex(int(time.time() * 1000))[2:])
|
|
o = o + genRandomString(30)
|
|
o = o + getPlatformCode(platform_type) + LOCAL_ID_SECRET_VERSION + "000"
|
|
o = o + str(crc32(o))
|
|
a1 = o[:52]
|
|
|
|
web_id = MD5(a1)
|
|
return a1, web_id
|
|
|
|
|
|
def get_comment(a1, xs, xt):
|
|
"""
|
|
通过调用node来获得x-comment参数
|
|
:param a1:
|
|
:param xs:
|
|
:param xt:
|
|
:return:
|
|
"""
|
|
url = "http://127.0.0.1:3000/xhs/get_comment"
|
|
data = {
|
|
"a1": a1,
|
|
"xs": xs,
|
|
"xt": xt
|
|
}
|
|
status, response = download_q(url, {}, {}, data=data)
|
|
return response.text
|
|
|
|
if __name__ == '__main__':
|
|
data = {
|
|
"source_note_id": "64bf4ea7000000000c035e48",
|
|
"image_formats": [
|
|
"jpg",
|
|
"webp",
|
|
"avif"
|
|
],
|
|
"extra": {
|
|
"need_body_topic": "1"
|
|
},
|
|
"xsec_source": "pc_feed",
|
|
"xsec_token": "ABSnHLvO9lnVSMKpZb-K1Cpn6d3xUC3z_mhRBvAbPGIe4="
|
|
}
|
|
data = json.dumps(data, ensure_ascii=False, separators=(',', ':'))
|
|
|
|
res = get_xs("191452e29d5vt5m5noazsyty9z4z3z695yoiu1pn130000168225", "/api/sns/web/v1/feed",data, "1723443461839")
|
|
print(res)
|