右键网页检查
搜索页面和这个相关的从而定位到引入文件
查找,一眼Base64编码的字体文件,通过这个编码数据解码获得原字体文件
找到之后进去查看
找到了,把里面内容复制下来,掐头去尾,是这样的数据
编写脚本进行解码,引号内填写base64编码数据去掉data:application/font-ttf;charset=utf-8;base64,
的开头声明”
1 | import base64 |
获得到base64的ttf文件结果
使用字体查看器查看字体 https://www.bejson.com/ui/font/
接下来将ttf文件转换成xml文件(python需要安装fontTools)
1 | from fontTools.ttLib import TTFont |
抽选字体对比一下映射结果对不对(超星的加密是修改了此字体图元数据,显示成未加密的字)
下载原来的字体文件(非超星加密后的文件)
源字体文件对应
超星加密后字体
也就是说原来的5148对应着57C3
编写对比代码进行测试
1 | import xml.etree.ElementTree as ET |
生成结果
1 | [ |
我采用的字符串是
超星:下埂关于“好好埃生”的埄埆哪埇不埁准埅?
思源:下面关于“好好先生”的描述哪项不太准确?
结合对照表显示,发现字体字形数据并对不上,查看字体数据,针对“下“字进行分析,发现两边结果并对不上,结果是超星对于字体字形进行了更改,并不是简单的对比字符哈希值就可以对比出来的了。
查看对比效果
左侧为原版字体,右侧为学习通字体
百度到” I Am I“大佬的文章”从学习通复制文字乱码看前端版权保护“找到一定的思路是假设字符的边距是唯一的,好的,那么我们就拼接边距距离。得出以下代码
1 | import xml.etree.ElementTree as ET |
再通过匹配结果进行查看数据
1 | import json |
得出结果
1 | 超星字体:下埂关于“好好埃生”的埄埆哪埇不埁准埅? |
在大佬的测试中,是可以确定90%左右的字符数据的。如果您不想看了,到这里就可以了,基本满足所有的效果了。
然后由于最近领导给我一些任务就是比较两个字符串的相似度,通过这个启发就想通过xy向量计算字符字形的相似度。得出以下代码,首先针对”下”字进行数据测试
归一化:将所有点归一化到相同的尺度。(如果不归一,DTW有要求长度一样,会报错)
归一化点集(Normalization of points)是指将原始点集中的每个点的坐标变换到一个特定的标准范围,以消除由于坐标范围不同而引起的差异,从而使得数据的比较更加公正和一致。具体而言,在这段代码中,归一化的目标是将每个点的坐标缩放到
[0, 1]
的范围内。为什么要进行归一化?
在计算点集之间的相似度时(如使用动态时间规整 DTW),不同的点集可能有不同的坐标范围或单位。如果不进行归一化,可能会因为坐标差异较大,导致计算出的相似度偏差较大。归一化的过程能够消除这种影响,让两个点集具有相同的尺度,从而公平地比较它们之间的相似性。
举个例子:
假设有一个点集:
1
points = [(10, 20), (30, 40), (50, 60), (70, 80)]
经过归一化处理后:
- 最小值:
min_x = 10
,min_y = 20
- 最大值:
max_x = 70
,max_y = 80
每个点将会变成:
(10, 20)
变成(0, 0)
(30, 40)
变成(0.333, 0.333)
(50, 60)
变成(0.666, 0.666)
(70, 80)
变成(1, 1)
最终,这些点就会被归一化到
[0, 1]
的范围内,这样它们的尺度是一致的,适合用于后续的相似度计算。归一化的目的是消除不同点集之间的坐标尺度差异,使得不同的点集可以在相同的尺度下进行比较。通过这种方式,我们可以更加公平地计算它们之间的相似度,而不会因为坐标的差异导致错误的比较结果。- 最小值:
使用DTW进行点对齐:保持原有的DTW对齐方法。
这里计算两个点集的相似度分数,通过DTW距离计算得出一个0~1的相似度分数。1完全相似,0完全不一样。
函数使用
fastdtw
函数计算归一化后的两个点集之间的 DTW 距离。DTW 是一种衡量两组时间序列相似度的算法,常用于处理不等长、速度不同的序列数据。在这里,它也可以用于比较两个二维点集的相似度。计算相似度:基于对齐后的点集计算相似度。
1 | import numpy as np |
得出结果
1 | Similarity score: 0.975700703557036 |
发现相似度还是很高的,这里是需要忽略字体的风格的,和笔画的这些。
好的,可以通过这种相似度算法去核对超星字体对应的元数据了。
1 | import xml.etree.ElementTree as ET |
但是运行效果不如人意
这么长的时间肯定是不能忍的,所有采用多线程的处理方式,cpu就应该忙起来了。
1 | from concurrent.futures import ProcessPoolExecutor, as_completed |
这样处理时间来到了半小时(不过cpu要满了),因为我要求把大于0.9的数据全弄出来了,所以会有很多重复的字形数据。这里还需要取出相似度最高的那一个字形数据。
1 | import json |
至此,我们以及彻底完成了映射表的制作。然后拿数据跑一下进行测试
1 | import json |
得出结果
1 | 超星字体:下埂关于“好好埃生”的埄埆哪埇不埁准埅? |
好的,已经可以了,这里关于超星字体的时候,有个疑问就是为什么每个页面加载页面的字体,不能拿到全部的,我这个不知道咋弄,很困扰我,希望有大佬可以帮忙解释一下。
至此,文章彻底结束。
参考文章:
关于超星学习通网页版字体加密分析 :https://www.52pojie.cn/thread-1631357-4-1.html
从学习通复制文字乱码看前端版权保护:https://5ime.cn/xxt_font.html