• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""fontTools.misc.eexec.py -- Module implementing the eexec and
2charstring encryption algorithm as used by PostScript Type 1 fonts.
3"""
4
5from __future__ import print_function, division, absolute_import
6from fontTools.misc.py23 import *
7
8def _decryptChar(cipher, R):
9	cipher = byteord(cipher)
10	plain = ( (cipher ^ (R>>8)) ) & 0xFF
11	R = ( (cipher + R) * 52845 + 22719 ) & 0xFFFF
12	return bytechr(plain), R
13
14def _encryptChar(plain, R):
15	plain = byteord(plain)
16	cipher = ( (plain ^ (R>>8)) ) & 0xFF
17	R = ( (cipher + R) * 52845 + 22719 ) & 0xFFFF
18	return bytechr(cipher), R
19
20
21def decrypt(cipherstring, R):
22	r"""
23	>>> testStr = b"\0\0asdadads asds\265"
24	>>> decryptedStr, R = decrypt(testStr, 12321)
25	>>> decryptedStr == b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1'
26	True
27	>>> R == 36142
28	True
29	"""
30	plainList = []
31	for cipher in cipherstring:
32		plain, R = _decryptChar(cipher, R)
33		plainList.append(plain)
34	plainstring = bytesjoin(plainList)
35	return plainstring, int(R)
36
37def encrypt(plainstring, R):
38	r"""
39	>>> testStr = b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1'
40	>>> encryptedStr, R = encrypt(testStr, 12321)
41	>>> encryptedStr == b"\0\0asdadads asds\265"
42	True
43	>>> R == 36142
44	True
45	"""
46	cipherList = []
47	for plain in plainstring:
48		cipher, R = _encryptChar(plain, R)
49		cipherList.append(cipher)
50	cipherstring = bytesjoin(cipherList)
51	return cipherstring, int(R)
52
53
54def hexString(s):
55	import binascii
56	return binascii.hexlify(s)
57
58def deHexString(h):
59	import binascii
60	h = bytesjoin(h.split())
61	return binascii.unhexlify(h)
62
63
64if __name__ == "__main__":
65	import sys
66	import doctest
67	sys.exit(doctest.testmod().failed)
68