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