1. 环境要求
当前网上很少找到类似的样例,之所以写一个是想自己整理一下,说是反爬其实就是提高反爬成本,其实根本很难杜绝反爬,更何况当前的AI识别更加难防。其实这里是模仿了起点小说的小说加密反爬虽然可能有不同只是实现效果差不多。
PHP >= 5.6 ,node.js ,composer ,一份完整的字体(这里以微软雅黑做测试 msyh.ttf)
npm 安装一些插件
npm install -g ttf2svg
//用法:ttf2svg fontello.ttf fontello.svg
npm install -g svg2ttf
npm install -g ttf2woff
2. 定义基础字体库
首先选择出要定义的基础字体比如 数字,基础符号,和一些常用字
吧微软雅黑字体(msyh.ttf)转为svg格式 (msyh.svg)(上面插件 可以自行转svg)
/**
* 基础模板生成
*/
public function baseCreateSvg()
{
//基础字
$baseWord = self::getBaseWord();
$xml = simplexml_load_string(file_get_contents(ROOT_PATH . "fonts/msyh.svg"));
$xml_json = json_encode($xml);
$xml_arr = json_decode($xml_json, true);
//把svg转为xml
$unicodeXml = $this->unicodeXmlBase($xml_arr, null, $baseWord);
//把xml自动转义的&符号 $amp; 替换为 &
$unicodeXml = str_replace('&', '&', $unicodeXml);
//这里生成基础模板根据基础模板生成多个模板 因为从头筛选字体文件会很大所以生成小型基础模板
$fileFont = ROOT_PATH . "fonts/" . "msyh_base" . ".svg";
file_put_contents($fileFont, $unicodeXml);
var_dump("生成成功路径: " . $fileFont);
}
定义基础字方法
此处举例就没定义太多:
/**
* 基础字
*/
private static function getBaseWord()
{
return [
'0', 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'O', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '(', ')', '.', '/', ':', ';', '<', '>', '=', '\\', '&', '?', '*', ',', '万', '三', '上', '下', '不', '与', '专', '且', '世', '业'
];
}
定义基础模板生成
/**
* 基础模板生成
* @param $arr
* @param null $parentNode
* @param array $baseWord
* @return mixed
*/
private function unicodeXmlBase($arr, $parentNode = null, $baseWord = [])
{
//如果父节点为null,则创建root节点,否则就使用父节点
if ($parentNode === null) {
$simxml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><svg></svg>');
} else {
$simxml = $parentNode;
}
//遍历数组
foreach ($arr as $k => $v) {
//再将xml转换成数组的时候,xml节点的属性会变成子数组,键名是@attributes,