# Fun.FontDecode
**Repository Path**: sephil/Fun.FontDecode
## Basic Information
- **Project Name**: Fun.FontDecode
- **Description**: 现在很多网站使用字体加密的方式来保护页面内容,即:你在页面上看到的文字内容不能直接复制或者下载下来,复制或下载得到的内容是乱码。 Fun.FontDecode 是一个 C# 编写的解密库,通过这个库可以解密得到原始的文字内容。
- **Primary Language**: C#
- **License**: BSD-3-Clause
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 1
- **Created**: 2020-05-24
- **Last Updated**: 2022-06-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Fun.FontDecode
#### 介绍
现在很多网站使用字体加密的方式来保护页面内容,即:你在页面上看到的文字内容不能直接复制或者下载下来,复制或下载得到的内容是乱码。
Fun.FontDecode 是一个 C# 编写的解密库,通过这个库可以解密得到原始的文字内容。
#### 加密原理
我们在显示器上看到的文字其本质其实是一种图形,计算机是不能直接处理图形的,所以我们需要将文字的图形保存下来,然后操作系统中制定一个对应的规则让文字与图形一一对应。其中,图形的集合就是我们所说的字体,而对应的规则就是文字的编码。当要显示一个文字时,操作系统根据文字的编码到字体中查找其对应的图形,然后将图形显示在屏幕上,这样我们才能够在屏幕上看到这个文字。举个例子,字母 A 的 ASCII 编码是 65,当操作系统要显示字母 A 时,会到字体中查找编码 65 对应的图形,然后把这个图形显示在屏幕上即可。如果使用不同的字体,那么我们看到的字母 A 的样子是不一样的,但是所有字体的提供者都会遵守同一个编码规则,即编码 65 代表的就是字母 "A"。
字体加密其实就是利用了这个规则,把文字编码和图形的对应规则全部打乱了,比如把图形 "A" 的对应编码改成 3456,虽然你在屏幕上看到的是 "A",但复制或下载下来的文字的编码其实是 3456,操作系统根据编码 3456 在正常的字体中得到的图形就不知道是个什么样的,所以这样的文字内容就没法在其他地方正常使用了。
目前字体加密方式有两种用法,一种是使用预先生成好的字体,然后输出时把文字转换成字体对应的编码,放到页面里显示即可。暂且叫它 **静态方式** 。这种方式解密,我们只需要找到字体文件,分析出编码对应规则后记录在代码里就可以了, **发布时不需要附带额外的文件** 。还有一种是每次页面显示时都重新生成一个新字体和编码对应规则,然后文字再做转换显示。这种我称为 **动态方式** 。两种方法本质上没有不同,只是第二种方式 **每次解密时都需要下载对应的字体文件进行分析和匹配** ,操作上繁琐一些。
#### 使用方法-静态
1. 分析页面和 CSS,找到字体文件的存放路径,下载到本地;
2. 用 Fun.FontDecode.Viewer 工具打开字体文件,就能看到文字的点阵图形与它对应的编码;
3. 填写 Viewer 右侧的文字与编码对应规则,如图中所示的, 对应字符 2, 对应字符 4;
4. 点击 Copy Static 按钮,Viewer 将自动生成字典代码并复制到剪贴板,然后将此代码粘贴到代码里;
4. 使用 `Fun.FontDecode.StaticFontDecoder` 解密。
参考如下代码:
```
static IDictionary FCharMapping = new Dictionary() {
复制的字典代码
};
string Decode(string text)
{
return new StaticFontDecoder(FCharMapping).Decode(text);
}
```
#### 使用方法-动态
这种方法解密要麻烦一些
1. 分析页面和 CSS,找到字体文件的存放路径,下载到本地;
2. 用 Fun.FontDecode.Viewer 工具打开字体文件,就能看到文字的点阵图形与它对应的编码;
3. 填写 Viewer 右侧的文字与编码对应规则,如图中所示的, 对应字符 2, 对应字符 4;
4. 点击 Copy Dynamic 按钮,Viewer 将自动生成字典代码并复制到剪贴板,然后将此代码粘贴到代码里;
5. 每次解密时必须 **先下载字体文件** ,再使用 `Fun.FontDecode.DynamicFontDecoder` 解密。
参考如下代码:
```
static IDictionary FCharMapping = new Dictionary() {
复制的字典代码
};
// 先下载 eot 字体文件,然后将字体文件作为参数传入
// EmbeddedOpenTypeParser 解析支持文件、流、字节数组、Base64编码的字体数据
// 这个示例里是将字体文件的所有内容作为字节数组传入
string Decode(byte[] fontSource, string text)
{
var eotParser = new EmbeddedOpenTypeParser();
eotParser.Parse(fontSource);
return new DynamicFontDecoder(eotParser.FontData, FCharMapping).Decode(text);
}
```
#### 其他说明
1. 基本上大部分网站的字体加密都只针对 0-9 和个别符号、汉字,分析的工作量不大的。
2. 动态加密时,生成的字体点阵图形会有一些偏差,如果解密得不到正确结果,将 `DynamicFontDecoder.ErrorRange` 放大一些试试。
3. 目前这个库只支持 eot 字体文件的解析,ttf、woff 解析没有测试过。不过一般页面上都会同时提供 eot 和 woff 字体。