主要是代码混淆,需要处理,处理后发现:典型MD5,但是验证不通过,魔改版本。
function getSign(input) {
// 关键改动:输入加盐
input = input + "\xA3\xAC\xA1\xA3fdjf,jkgfkl";
return md5(input);
}
function md5(str) {
return hex(md5_cycle(str2binl(str), str.length * 8));
}
function md5_cycle(x, len) {
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
// 填充
x[len >> 5] |= 0x80 >> 9)
T3
(1)
https://www.spiderdemo.cn/static/protos/challenge.proto 生成一个 .proto 文件
转换为 python 调用 (authentication_pb2.py)
计算 signature
function get_sign(){
const timestamp = Date['now']()
const timestampStr = timestamp["toString"]();
const signature = md_sign['OooO'](timestampStr);
return [timestamp,signature]
}
其中 加密函数md_sign 一看四个初始值,很像md5,但是肯定是魔改了。
然后就是 protobuf 请求: 大概这样 类似 (所有人代码肯定存在差异,大胆修改)
request_msg = authentication_pb2.ChallengeRequest()
request_msg.page = page
request_msg.challengetype = "surwrexibfkdoohqjh"
request_msg.timestamp = timestamp # 确保是 int 类型
request_msg.signature = signature # 确保是 string 类型
# 1. 本地序列化
data = request_msg.SerializeToString()
try:
test_msg = authentication_pb2.ChallengeRequest()
test_msg.ParseFromString(data)
except Exception as e:
print(f"Protobuf 格式错误: {e}")
结果:
T7 CSS1_challenge
"""
:root { --offset-0-4244: calc(max((2 3 5px), (2 3 5px))); --offset-1-4629: calc(min((3 5px), (3 5px))); --neg-2-2731: calc(-1 var(--offset-1-4629)); --offset-3-6224: calc((3 5px) / 1 1); } 三 五" style="position:relative;left:var(--offset-0-4244)">7 e" style="position:relative;left:var(--neg-2-2731)">649
"""
(1) 计算style 中的函数 (有的没有style)
① 没有style
if '' not in html_code:
html_code = re.sub(r'', '', html_code)
style = re.sub(r'', '', html_code).strip()
digits_with_offset = [(digit, 0) for digit in re.findall(r'[0-9]', html_code)]
return move_by_offset(digits_with_offset)
move_by_offset 是根据当前位置进行移动操作
② 处理style
类似下面的一些处理方法:
def eval_calc(self, expr):
expr = expr.strip()
expr = self.replace_chinese_numerals(expr)
var_pattern = r'var\(--[^)]+\)'
while re.search(var_pattern, expr):
var_match = re.search(var_pattern, expr)
var_name = var_match.group(0)[4:-1] # 提取变量名
var_value = self.variables.get(var_name, 0)
expr = expr.replace(var_match.group(0), str(var_value))
try:
# 替换运算符号周围的空格
expr = re.sub(r'\s*([+\-*/()])\s*', r'\1', expr)
expr = expr.replace('px','')
return self.parse_number(str(eval(expr)))
except Exception as e:
print(f"计算表达式错误: {expr}, 错误: {e}")
return 0
def parse_number(self, s):
s = s.strip().replace('px', '') # 移除单位
if s.startswith('0x'):
return int(s, 16)
elif s.startswith('0b'):
return int(s, 2)
else:
return float(s) if '.' in s else int(s)
def extract_digits(html_code):
soup = BeautifulSoup(html_code, 'html.parser')
digits_with_offset = []
evaluator = CSSEvaluator()
if '' not in html_code:
# style = re.sub(r'', '', html_code,flags=re.DOTALL)
html_code_no = re.sub(r'', '', html_code)
style = re.sub(r'', '', html_code_no).strip()
digits_with_offset = [(digit, 0) for digit in re.findall(r'[0-9]', style)]
return move_by_offset(digits_with_offset)
# 解析CSS变量
style_tag = soup.find('style')
if style_tag and style_tag.string:
evaluator.parse_css_variables(style_tag.string)
# print(evaluator.variables)
html_code1 = re.sub(r'', '', html_code)
# print(html_code1)
result = html_code1.split('')
start_num,end_num,digit,style = '','','',''
for item in result:
# print('item',item.strip())
if item == '':
continue
if item.strip().isdigit():
# print('end',item)
end_num = item.strip()
else:
if item.strip()[0].isdigit():
start_num = item.split('
...
(2) 处理文本的数据
① 获取数字和位置信息
这里 处理需要注意很多细节,比如 很多数据没有 在span标签中,如何处理,
"position:relative' 是否存在 ,left: 还是right: 等
3.结果
T9 font_sprites_challenge (一种思路)
[ol]
计算相似度
def calculate_hash(image_path):
"""计算图片的感知哈希值"""
img = cv2.imread(image_path)
if img is None:
raise ValueError(f"无法读取图片: {image_path}")
img = cv2.resize(img, (8, 8), interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
avg = gray.mean()
hash_str = ""
for i in range(8):
for j in range(8):
# 如果像素值大于平均值则为1,否则为0
hash_str += "1" if gray[i, j] > avg else "0"
return hash_str
def hamming_distance(hash1, hash2):
if len(hash1) != len(hash2):
raise ValueError("两个哈希值长度必须相同")
return sum(c1 != c2 for c1, c2 in zip(hash1, hash2))
[/ol]
def image_similarity(image1_path, image2_path):
计算哈希值
hash1 = calculate_hash(image1_path)
hash2 = calculate_hash(image2_path)
distance = hamming_distance(hash1, hash2)
similarity = 1 - distance / 64
return similarity
```
[/ol]
T10 font_svg_challenge
[ol]
python
def parse_data(data):
paths = re.findall('
[/ol]
T16 slide_scratch_challenge
[ol]
2 通过提示词,和物体信息 计算移动距离
由于下载的图片可以看见信息 这里首先对提示词整理,大概十几个类别,同时对物体信息检测分隔(yolo)。
计算这里 可以训练分类模型 ,或者相似度模型
ResNet50 残差神经网络可以进行分类训练
3.验证token
[/ol]
T17 slide_puzzle_challenge
[ol]
获取图片
2 计算距离
这里分隔图片 上下,使用边缘算子,计算拼接相似度,每次移动一个像素。选择最合理的距离
def calculate_distance(image_path, split_y=99):
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
upper = gray[:split_y, :] # 上半部分(需要移动的区域)
lower = gray[split_y:, :] # 下半部分(固定区域)
upper_edges = cv2.Canny(upper, xxxx, xxxxxx) #自己参数调整
contours, _ = cv2.findContours(upper_edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if not contours:
raise ValueError("未检测到上半部分轮廓,请调整边缘检测参数")
cnt = max(contours, key=lambda c: cv2.contourArea(c))
x, y, w, h = cv2.boundingRect(cnt) # 上半部分轮廓的边界框
print(x, y, w, h )
result = cv2.matchTemplate(lower, upper_edges, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
match_x, _ = max_loc # 匹配到的水平坐标
distance = match_x - x
return distance
验证token
处理细节 获取结果
[/ol]
T18 cap6_challenge
[ol]
获取图片
通过cv2 或者dddd 计算两次距离
计算结果
[/ol]
“”“个人觉得 这个比较简单了。 ”“”
T19 slide_cylinder_challenge
上一篇已经写了。
补充点:
(1)计算轨迹(x,y,t) tracks = track[:-50]
def get_distince():
# 读取图像
image = cv2.imread('img.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Canny边缘检测
edges = cv2.Canny(gray, 50, 150)
# 寻找轮廓(用于确定人物区域)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
person_x = 100
# 假设最大的轮廓是人物(实际需根据图像情况调整)
if contours:
largest_contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(largest_contour)
person_x = x
else:
print("未检测到轮廓")
return person_x
def on_mouse_move(currentX, clientY,timestamp):
max_container = 400
minX, maxX = 0x118, max_container - 0x46 # 280, 334
currentX = max(0, min(maxX, currentX)) #
# slideDistance = currentX
# targetAngle = currentX / maxX * 360 # 0x168 = 360°
posX = currentX / maxX * 350 # 0x15e = 350
record = {
'x': posX,
'y': clientY,
'timestamp': timestamp
}
return record
(2) 计算的轨迹 的编码不是标准的
编码可以直接根据js 改写即可。
T20 cap8_challenge
[ol]
目标检测 分隔图片
图片标注
进行相似度模型训练
可以借鉴这个帖子
计算获取结果
3 请求 注意细节
[/ol]
“”“ 这道题不难,但可能是最麻烦的”“”
T26 click_stitch_challenge
[ol]
def solve_puzzle_fixed_layout(img_path, inner_gap=8, outer_gap=8, strip=5):
"""
逻辑:
"""
[/ol]
总结:
大多数不难,但是部分处理起来费时间。

