《封号码罗》关于js逆向猿人学第七题动态字体的解决办法(二十八)

首先需要获取动态字体,第七题的字体文件在接口返回值里面

import base64
from io import BytesIO
from bs4 import BeautifulSoup
import requests
from fontTools.ttLib import TTFont  # pip install fonttools

headers = {
    'User-Agent': 'yuanrenxue.project'
}

res = requests.get(f'http://match.yuanrenxue.com/api/match/7?page=1', headers=headers)
data = res.json()
data_list = data["data"]
# print(data_list)
woff = data["woff"]
with open("7.woff", "wb") as f:
    f.write(base64.b64decode(woff))

font = TTFont("7.woff")
font.saveXML("7x.xml")

打开字体xml文件,多次测试之后发现,这个字体文件也是动态的,但是glyf对应的一直是0-9之间的数字,注意:对应顺序是动态的在这里插入图片描述
但是on对应的这一列一直是不变的
在这里插入图片描述

glyf = font.getGlyphSet()
glyf_name = font.getGlyphNames()
on_dict = {}
for index, name in enumerate(glyf_name[1:]):
    # 读取 glyf 表, 获取各字形对应的 on 值
    on_data = font['glyf'][name].flags
    # 字符串拼接
    on_key = "".join([str(n) for n in on_data])
    # 组合字典
    on_dict[on_key] = name
print(on_dict)

可以得到如下对应关系:
在这里插入图片描述
整理之后:

old_map = {'10100100100101010010010010': 'unia146',
           '111111111111111': 'unia396',
           '10010101001110101011010101010101000100100': 'unia426',
           '101010101101010001010101101010101010010010010101001000010': 'unia618',
           '100110101001010101011110101000': 'unia928',
           '1111111': 'unib387',
           '10101100101000111100010101011010100101010100': 'unib542',
           '1110101001001010110101010100101011111': 'unic368',
           '1001101111': 'unic472',
           '10101010100001010111010101101010010101000': 'unic832'
           }

这里注意的是,key不变,变的是value,但value代表的数字是不变的,如

'1111111': 'unib387'
'1111111': 'unib173'

实际上都是数字7:

'1111111': 7
'1111111': 7

可以使用: 字体处理工具,查看字体文件里面的对应关系
在这里插入图片描述
完整代码:

import base64
from io import BytesIO
from bs4 import BeautifulSoup
import requests
from fontTools.ttLib import TTFont  # pip install fonttools

headers = {
    'User-Agent': 'yuanrenxue.project'
}

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

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

values = {}
for index in range(1, 6):
    res = requests.get(f'https://match.yuanrenxue.cn/api/match/7?page={index}', headers=headers)
    data = res.json()

    # 用二进制流的方式保存字体文件
    # font_bytes = BytesIO(base64.b64decode((data.get("woff")).encode()))
    # font = TTFont(font_bytes)
    with BytesIO(base64.b64decode((data.get("woff")).encode())) as font_web_bytes:
        font = TTFont(font_web_bytes)
    with BytesIO() as font_local_bytes:
        font.saveXML(font_local_bytes)  # 保存成xml格式的文件到二进制流(内存中)
        # 获取字体文件的二进制数据 font_local_bytes.getvalue()
        ids = BeautifulSoup(font_local_bytes.getvalue(), 'xml').find('glyf').find_all('TTGlyph')

    # 映射数字关系
    gid = {}
    for g in ids:
        gid[g['name']] = new_map[''.join(b['on'] for b in g.find_all('pt'))]

    # {'.notdef': '', 'unia139': '1', 'unia249': '6', 'unib485': '9', 'unib752': '0', 'unib792': '4', 'unib812': '2', 'unib856': '5', 'unib935': '7', 'unic165': '8', 'unic586': '3'}
    for i, d in enumerate(data['data']):
        values[name_list[i + 1 + (index - 1) * 10]] = int(
            ''.join(gid[dd.replace('&#x', 'uni')] for dd in d['value'].strip().split(' ')))
print(max(values, key=lambda v: values[v]))

参考学习链接:
https://blog.youkuaiyun.com/Yy_Rose/article/details/126704652
https://blog.youkuaiyun.com/user_from_future/article/details/130259277

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值