当前位置: 首页 > news >正文

【中等】 猿人学web第一届 第7题 动态字体,随风漂移

文章目录

  • 获取字体文件映射关系
  • 获取页面英雄排序
  • python 代码

这道题是 动态字体文件加密,找出动态字体文件中对应数字相同规律即可

数据接口 https://match.yuanrenxue.cn/api/match/7
数据接口没有加密值 cookie字段也没有
在这里插入图片描述

获取字体文件映射关系

多次观察 字体文件代表数字对应的 on 值是不变的
unia126 和 unic195 对应的数字都为 1,对应的 on 值都是相同的
在这里插入图片描述在这里插入图片描述
根据 数字对应的on值,编写一个映射字典

from fontTools.ttLib import TTFont  # pip install fontTools
from base64 import b64decode
from parsel import Selector  # pip install parseldef demo(data):"""data为接口返回的内容"""with open('7.ttf', mode='wb') as file:file.write(b64decode(data['woff']))  # 将 woff 字段 b64解码后写入到文件font = TTFont('7.ttf')  # 加载字体文件font.saveXML('7.xml')  # 保存为xml文件# 读取 xml 文件with open('7.xml', mode='r', encoding='utf-8') as f:xml_data = f.read()select = Selector(xml_data)glyf = select.css('glyf > TTGlyph')  # 获取 glyf 下所有的 TTglyph 标签for TTGlyph in glyf[1:]:  # 第 0 个标签的值是不需要的,所以从 第 1 个元素开始遍历name = TTGlyph.css('::attr(name)').get().replace('uni', '')  # 获取 TTGlyph 标签里对应的 name 属性,并将 uni 替换为空pt_tag = TTGlyph.css('pt')  # 获取 TTGlyph 下所有的 pt 标签on_list = []for pt in pt_tag:  # 遍历 pt 标签on = pt.css('::attr(on)').get()  # 获取 pt 标签里对应的 on 属性on_list.append(on)  # 将解析的到 on 属性值添加到列表中print(f"'{''.join(on_list)}': '{name}',")  # 打印出字典形式的字符串# ''.join(on_list) 对应字典键# name 对应字典值if __name__ == '__main__':demo(# 这里放入接口返回的数据 copy 即可)

运行结果
在这里插入图片描述

再将对应编码替换成正确的数字即可
在这里插入图片描述

解析得到的映射字典 ↓

on_map = {'1001101111': '1','101010101101010001010101101010101010010010010101001000010': '8','10101010100001010111010101101010010101000': '6','10100100100101010010010010': '0','1110101001001010110101010100101011111': '5','10010101001110101011010101010101000100100': '9','100110101001010101011110101000': '2','111111111111111': '4','1111111': '7','10101100101000111100010101011010100101010100': '3',
}

有了映射字典就可以请求并解析到正确的数字了

def save_font(font_data):on_map = {'1001101111': '1','101010101101010001010101101010101010010010010101001000010': '8','10101010100001010111010101101010010101000': '6','10100100100101010010010010': '0','1110101001001010110101010100101011111': '5','10010101001110101011010101010101000100100': '9','100110101001010101011110101000': '2','111111111111111': '4','1111111': '7','10101100101000111100010101011010100101010100': '3',}with open('7.ttf', mode='wb') as f:f.write(b64decode(font_data['woff']))  # 保存字体文件font = TTFont('7.ttf')  # 加载字体文件font.saveXML('7.xml')  # 保存为xml文件# 读取 xml 文件with open('7.xml', mode='r', encoding='utf-8') as f:xml_data = f.read()select = Selector(xml_data)# 获取 <glyf> --> 所有 TTGlyph 标签TTGlyph = select.css('glyf > TTGlyph')[1:]  # 第 0 个标签的信息不需要,从第 1 个标签开始获取rep_dist = {}for tt in TTGlyph:name = tt.css('::attr(name)').get().replace('uni', '')  # TTGlyph标签 --> name 值pt = tt.css('pt')  # 获取 Glyph标签 --> TTGlyph标签 --> pt标签对应的 on 值on_list = []for pt_tag in pt:on_list.append(pt_tag.css('::attr(on)').get())rep_dist[name] = on_map[''.join(on_list)]  # 根据映射将 on 值替换成正确的数字result_dict = []for data in font_data['data']:num_list = []for nums in data['value'].replace('&#x', '').split(' ')[0:-1]:num_list.append(rep_dist[nums])result_dict.append(int(''.join(num_list)))#     print(rep_dist[nums], end='')# print()return result_dict

运行结果
在这里插入图片描述

获取页面英雄排序

每页英雄的排序是在 js 中做处理的, 在数据接口的 requests 栈
在这里插入图片描述

对应的 js 代码

let page = 1;
let name = ['极镀ギ紬荕', '爷灬霸气傀儡', '梦战苍穹', '傲世哥', 'мaη肆風聲', '一刀メ隔世', '横刀メ绝杀', 'Q不死你R死你', '魔帝殤邪', '封刀不再战', '倾城孤狼', '戎马江湖', '狂得像风', '影之哀伤', '謸氕づ独尊', '傲视狂杀', '追风之梦', '枭雄在世', '傲视之巅', '黑夜刺客', '占你心为王', '爷来取你狗命', '御风踏血', '凫矢暮城', '孤影メ残刀', '野区霸王', '噬血啸月', '风逝无迹', '帅的睡不着', '血色杀戮者', '冷视天下', '帅出新高度', '風狆瑬蒗', '灵魂禁锢', 'ヤ地狱篮枫ゞ', '溅血メ破天', '剑尊メ杀戮', '塞外う飛龍', '哥‘K纯帅', '逆風祈雨', '恣意踏江山', '望断、天涯路', '地獄惡灵', '疯狂メ孽杀', '寂月灭影', '骚年霸称帝王', '狂杀メ无赦', '死灵的哀伤', '撩妹界扛把子', '霸刀☆藐视天下', '潇洒又能打', '狂卩龙灬巅丷峰', '羁旅天涯.', '南宫沐风', '风恋绝尘', '剑下孤魂', '一蓑烟雨', '领域★倾战', '威龙丶断魂神狙', '辉煌战绩', '屎来运赚', '伱、Bu够档次', '九音引魂箫', '骨子里的傲气', '霸海断长空', '没枪也很狂', '死魂★之灵'];
let heroArray = []
for (let i = 0; i <= 4; i++) {let yyq = 1;// ['', '', '', '', '', '', '', '', '', ''] 对应一页十条数据['', '', '', '', '', '', '', '', '', ''].forEach((index, val) => {// console.log(name[yyq + (page - 1) * 10]);heroArray.push(name[yyq + (page - 1) * 10])yyq += 1})page += 1;
}
console.log(heroArray)

运行结果
在这里插入图片描述

python 代码

import requests
from base64 import b64decode
from fontTools.ttLib import TTFont  # pip install fontTools
from parsel import Selectorheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
cookies = {"sessionid": "你的SessionId"
}def send_match6(page):url = "https://match.yuanrenxue.cn/api/match/7"params = {"page": f"{page}"}response = requests.get(url, headers=headers, cookies=cookies, params=params)return {'woff': response.json()['woff'],'data': response.json()['data']}def save_font(font_data):on_map = {'1001101111': '1','101010101101010001010101101010101010010010010101001000010': '8','10101010100001010111010101101010010101000': '6','10100100100101010010010010': '0','1110101001001010110101010100101011111': '5','10010101001110101011010101010101000100100': '9','100110101001010101011110101000': '2','111111111111111': '4','1111111': '7','10101100101000111100010101011010100101010100': '3',}with open('7.ttf', mode='wb') as f:f.write(b64decode(font_data['woff']))  # 保存字体文件font = TTFont('7.ttf')  # 加载字体文件font.saveXML('7.xml')  # 保存为xml文件# 读取 xml 文件with open('7.xml', mode='r', encoding='utf-8') as f:xml_data = f.read()select = Selector(xml_data)# 获取 <glyf> --> TTGlyphTTGlyph = select.css('glyf > TTGlyph')[1:]  # 第 0 个标签的信息不需要,从第 1 个标签开始获取rep_dist = {}for tt in TTGlyph:name = tt.css('::attr(name)').get().replace('uni', '')  # TTGlyph标签 --> name 值pt = tt.css('pt')  # 获取 Glyph标签 --> TTGlyph标签 --> pt标签对应的 on 值on_list = []for pt_tag in pt:on_list.append(pt_tag.css('::attr(on)').get())rep_dist[name] = on_map[''.join(on_list)]  # 根据映射将 on 值替换成正确的数字result_dict = []for data in font_data['data']:num_list = []for nums in data['value'].replace('&#x', '').split(' ')[0:-1]:num_list.append(rep_dist[nums])result_dict.append(int(''.join(num_list)))#     print(rep_dist[nums], end='')# print()return result_dictif __name__ == '__main__':hero_array = ['爷灬霸气傀儡', '梦战苍穹', '傲世哥', 'мaη肆風聲', '一刀メ隔世', '横刀メ绝杀', 'Q不死你R死你', '魔帝殤邪', '封刀不再战', '倾城孤狼','戎马江湖', '狂得像风', '影之哀伤', '謸氕づ独尊', '傲视狂杀', '追风之梦', '枭雄在世', '傲视之巅', '黑夜刺客', '占你心为王', '爷来取你狗命', '御风踏血', '凫矢暮城', '孤影メ残刀', '野区霸王', '噬血啸月', '风逝无迹', '帅的睡不着', '血色杀戮者', '冷视天下','帅出新高度', '風狆瑬蒗', '灵魂禁锢', 'ヤ地狱篮枫ゞ', '溅血メ破天', '剑尊メ杀戮', '塞外う飛龍', '哥‘K纯帅', '逆風祈雨', '恣意踏江山', '望断、天涯路', '地獄惡灵', '疯狂メ孽杀', '寂月灭影', '骚年霸称帝王', '狂杀メ无赦', '死灵的哀伤', '撩妹界扛把子', '霸刀☆藐视天下', '潇洒又能打']  # 正确的英雄排序列表hero_nums = []  # 声明一个列表,用于存储所有的数值for page in range(1, 6):math6_data = send_match6(page)nums_list = save_font(math6_data)print(page, nums_list)  # 打印请求的页数,对应的列表(数值)for num in nums_list:  # 遍历每页得到的列表hero_nums.append(num)  # 将列表数值添加到 hreo_nums 列表中print(hero_nums)  # 打印所有页面的数值max_num = 0  # 定义一个变量,用于存储最大的数值for num in hero_nums:# 将 hero_nums 中的每一个数值与 max_num 作比较if num > max_num:  # 如果改数值比 max_num 大max_num = num  # max_num 就等于改数值hero_index = hero_nums.index(max_num)  # 获取列表中最大数值的索引print(hero_array[hero_index])  # 获取对应英雄列表的英雄名

http://www.mrgr.cn/news/1064.html

相关文章:

  • 华为 OLT 添加 ONT 配置 (OMCI 管理模式)
  • 清理 Conda 缓存和 Pip 缓存
  • 【hot100篇-python刷题记录】【矩阵置零】
  • 零基础学习Redis(5) -- redis单线程模型介绍
  • 第一篇:fiddler学习日记配置抓取https和http
  • 二:《Python基础语法汇总》— 条件判断与循环结构
  • 模电实验4 - 单电源直接耦合放大电路
  • 【Qt】Qt窗口 | QDockWidget 浮动窗口
  • python使用flask实现自动根据url寻找对应目录/文件/方法,实现动态路由
  • xss GAME (xss漏洞攻击1-8)
  • html文件运行后界面反馈xxx拒绝连接
  • leetcode 552. 学生出勤记录 II
  • 用ChatGPT出题,完全做不完
  • 24 初入python
  • 每日一题,力扣leetcode Hot100之189.轮转数组
  • 8月15日笔记
  • 贝克资本再发力,新兴数字项目引领亚洲投资新潮
  • java 函数接口Consumer简介与示例【函数式编程】【Stream】
  • 解决k8s分布式集群,子节点加入到主节点失败的问题
  • golang Kratos 概念