python学习T字体加密分析

前言:本篇仅作为技术交流分析学习T字体加密的方式,给爬虫爱好者们提供一些思路。

如果你想要爬取学习T的作业题可以看这篇:python爬虫笔记(学习T)_星空的你的博客-CSDN博客

首先:经过我的观察学习T并非所有页面都有字体加密,有加密的页面一般为作业和章节测试,并且当提交完作业或测试后,字体加密会消失,加密的方式为随机选择文字进行加密。

特点:被加密的页面必有base64编码,直接在页面源码中搜索base64(base64后面的一大长串就是加密字体的映射文件,直接复制在浏览器放入url中回车下载)即可。但有时侯不会出现字体加密很奇怪,判断是否有加密的方法很简单直接复制题目,粘贴到文本中看文字就知道了。

补充:学习T采用iframe嵌套的方式将内容嵌套进网页,使用selenium爬取时需要注意,一般我们爬取的页面需要进入3层iframe,但有的页面就两层iframe或一层,导致如果把方法写死运行会一直报错,如果你想爬取所有页面必须进行try:expect。

思路一:建立映射

可以在python中定义一个方法,将base64解码成xml文件,用到的库自行下载

from fontTools.ttLib import TTFont, BytesIO
def make_font_file(base64_string,):
    bin_data = base64.decodebytes(base64_string.encode())
    font = TTFont(BytesIO(bin_data))
    font.saveXML("text.xml")

得到下面的文件,图中name是uni编码对应某一文字,下方x,y为点坐标,所有点坐标能描绘出一个文字的轮廓

 可以先使用字体显示软件,看一下对应关系,如下图所示:图中非学习T加密字体,因为字体文件被我删了,用的是思源字体文件(下面需要用到它)

 学习T通过更改uni编码的方式将映射给改了,比如把上图中‘至’和‘臼’的uni编码换一下,那么现在网页上显示的所有‘至’其实是‘臼’,而他们内部自有他们的一套映射关系文件,这个文件就是我们拿到的base64编码,转码所得的xml文件。

虽然uni编码更改了,但是下方的x,y坐标等信息如果不改变的话我们只需要拿到一套学习T的映射关系文件和一份原本uni编码(就是上面的思源字体文件)的映射关系文件,通过匹配一个字中所有x,y的点信息就能还原被替换的文字,然而事实真的如此吗?我们试试看。

说明:原本uni编码(就是上面的思源字体文件)并非固定的,一个网站一种文件,也可能不只一种,从学习T的加密字体文件中得知的源文件信息(保存为ttf后双击打开)百度下载的,如图:

代码:

import ast
import re
import hashlib
from fontTools.ttLib import TTFont


def makeXml(fail):
    font = TTFont(fail)
    font.saveXML("source.xml")
#makeXml("source.ttf")
#md5加密方法
def md5(s):
    m = hashlib.md5()
    m.update(s.encode())  # 字符串不能直接加密,要先转化成二进制
    res = m.digest()  # 返回二进制十六位
    res2 = m.hexdigest()  # 返回十六进制三十二位
    return res2


#创建加密字体映射字典
def creatMapping(fail):
    MapDict = {}
    with open(fail,'r',encoding='utf8') as f:
        text = f.read()
    #一个TTGlyph对应一个字
    TTGlyphs = text.split("</TTGlyph>")[:-1]
    #外层循环处理所有文字,第一个无用的直接跳过
    for i in range(1, len(TTGlyphs)):
        #一个word列表只装一个文字的映射关系
        word = []
        contour = re.findall('<pt (.*?)/>', TTGlyphs[i])
        #name就是uni编码
        name=re.findall('name="(.*?)"',TTGlyphs[i])[0]

        if (len(name) != len('uni2015') or name[0:3]!='uni'):
            continue
        #内层循环处理一个文字的映射关系
        for j in range(0, len(contour)):
            x = re.findall('x=\"(.*?)\"', contour[j])
            y = re.findall('y=\"(.*?)\"', contour[j])
            on = re.findall('on=\"(.*?)\"', contour[j])
            #将所有点的信息存进一个列表,此列表为该uni编码对应的文字信息
            word.append(x[0] +','+y[0] +','+on[0])
        #用MD5加密创建唯一标识,其实不加密也行,其实就是减少计算机运行的压力,不加密的话要判断列表整个列表是否相等,加密后判断32位字符串是否相等

        MapDict[name.replace("uni","\\u").encode("utf-8").decode('unicode_escape')]=md5(str(word))
    # with open('Source.txt','w',encoding='utf8')as f:
    #     f.write(str(MapDict))
    return MapDict


#creatMapping('Source.xml')


#撞库匹配
def decode(fail):
    replaceDict={}
    with open('Source.txt','r',encoding='utf8') as f:
        Source=f.read()
    SourceDict=ast.literal_eval(Source)

    MapDict=creatMapping(fail)
    for mapKey,mapValue in MapDict.items():
        print(mapKey)
        for sourceKey,sourceValue in SourceDict.items():
            if(mapValue==sourceValue):
                replaceDict[mapKey]=sourceKey
                break
    return replaceDict


for key,value in decode('text.xml').items():
    print(key+":"+value)

 用一个方法创建两套字典,撞库匹配,匹配结果如下图所示:

可以看到10个学习T加密字体从思源的库中只撞到了三个,他喵的什么情况?

我抽根烟,稍微冷静思考了一下,猜测可能有两种可能:

一:学习T不只用了一套字体库(可能性小,因为没必要)

二:学习T魔改了字体文件,可能稍微调整了文件中某些字的x,y的值,导致MD5撞库失败

三:其他手段,不在我的理解范围内。

 但无论是以上哪种可能,处理起来都及其麻烦(如果你要手动创建映射库的话当我没说)

学习T可真精明啊,还真不是我们这些学生的水平能对抗的,哎。

不过兵来将档,水来土掩,这条路走不通,我们不妨换个思路,前面已经说了,我们是可以拿到学习T加密字体的uni编码和所有点信息的,python使用PIL绘图可以通过这些点坐标画出文字的图片

没错,图片就是正确文字的图形化,而uni编码就是加密字体,这样其实也可以创建映射关系,只不过创建的是加密字和正确字图片的映射关系,我们可以通过绘图保存图片再通过OCR文字识别来识别出文字,间接创建文字对应,但有个问题就是识别准确率的问题,这个问题相当之恶心了,因为python的文字识别库准确率简直低的离谱,所以我打算借助网上的在线识别网站,用selenium完成自动化识别,这就是思路二了,完整的操作流程我放到下一篇来讲。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值