-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsec_font.py
83 lines (73 loc) · 2.71 KB
/
sec_font.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import base64
import hashlib
import re
import sqlite3
import struct
from io import BytesIO
from pathlib import Path
from typing import IO, Dict, Union
from colorama import Back, Fore, Style
from fontTools.ttLib.ttFont import TTFont
class FontHashDAO:
def __init__(self, file='font_hashmap.db'):
self.conn = sqlite3.connect(file)
def findChar(self, fontHash: str) -> str:
cur = self.conn.execute("SELECT cn_char FROM hashmap WHERE hash=(?)", (fontHash,))
if resp := cur.fetchone():
return resp[0]
def findHash(self, char: str) -> str:
cur = self.conn.execute("SELECT hash FROM hashmap WHERE cn_char=(?)", (char,))
if resp := cur.fetchone():
return resp[0]
def secFont2Map(file: Union[IO, Path, str]) -> Dict[str, str]:
'以加密字体计算hashMap'
fontHashMap = {}
if isinstance(file, str):
file = BytesIO(base64.b64decode(file[47:]))
with TTFont(file) as fontFile:
glyphs = fontFile.getGlyphSet()
for code, font in dict(glyphs).items():
if not code.startswith('uni'):
continue
fontHash = hashlib.sha256()
for pos in font._glyph.coordinates:
fontHash.update(struct.pack('>2i', *pos))
fontHashMap[code] = fontHash.hexdigest()
return fontHashMap
def secFontDec(hashMap, source) -> str:
'解码字体加密'
dao = FontHashDAO()
resultStr = ''
for char in source:
unicodeID = f'uni{ord(char):X}'
if (fontHash := hashMap.get(unicodeID)):
originChar = dao.findChar(fontHash)
if originChar is not None:
resultStr += originChar
else:
print(Fore.RED+f'解码失败: {char}({fontHash})'+Fore.RESET)
else:
resultStr += char
print(Fore.GREEN+f'字体加密解码: {source} -> {resultStr}'+Fore.RESET)
return resultStr
def secFontEnc(hashMap, source) -> str:
'编码字体加密'
dao = FontHashDAO()
hashMap = dict(zip(hashMap.values(), hashMap.keys()))
resultStr = ''
for char in source:
if (fontHash := dao.findHash(char)):
if (unicodeID := hashMap.get(fontHash)):
if (result := re.match(r'^uni([0-9A-Z]{4})$', unicodeID)):
encChar = chr(int(result.group(1), 16))
resultStr += encChar
else:
resultStr += char
else:
resultStr += char
print(Fore.GREEN+f'字体加密编码: {source} -> {resultStr}'+Fore.RESET)
return resultStr
if __name__ == "__main__":
import rich
fontHashMap=secFont2Map(Path('../../../Desktop/Source Han Sans CN Normal.pfb.ttf'))
rich.print(fontHashMap)