Just | 6c53f88 | 2000-01-12 19:15:12 +0000 | [diff] [blame] | 1 | """fontTools.misc.eexec.py -- Module implementing the eexec and |
| 2 | charstring encryption algorithm as used by PostScript Type 1 fonts. |
| 3 | """ |
| 4 | |
| 5 | # Warning: Although a Python implementation is provided here, |
| 6 | # all four public functions get overridden by the *much* faster |
| 7 | # C extension module eexecOp, if available. |
| 8 | |
| 9 | import string |
| 10 | |
| 11 | error = "eexec.error" |
| 12 | |
| 13 | |
| 14 | def _decryptChar(cipher, R): |
| 15 | cipher = ord(cipher) |
| 16 | plain = ( (cipher ^ (R>>8)) ) & 0xFF |
| 17 | R = ( (cipher + R) * 52845L + 22719L ) & 0xFFFF |
| 18 | return chr(plain), R |
| 19 | |
| 20 | def _encryptChar(plain, R): |
| 21 | plain = ord(plain) |
| 22 | cipher = ( (plain ^ (R>>8)) ) & 0xFF |
| 23 | R = ( (cipher + R) * 52845L + 22719L ) & 0xFFFF |
| 24 | return chr(cipher), R |
| 25 | |
| 26 | |
| 27 | def decrypt(cipherstring, R): |
| 28 | # I could probably speed this up by inlining _decryptChar, |
| 29 | # but... we've got eexecOp, so who cares ;-) |
| 30 | plainList = [] |
| 31 | for cipher in cipherstring: |
| 32 | plain, R = _decryptChar(cipher, R) |
| 33 | plainList.append(plain) |
| 34 | plainstring = string.join(plainList, '') |
| 35 | return plainstring, int(R) |
| 36 | |
| 37 | def encrypt(plainstring, R): |
| 38 | cipherList = [] |
| 39 | for plain in plainstring: |
| 40 | cipher, R = _encryptChar(plain, R) |
| 41 | cipherList.append(cipher) |
| 42 | cipherstring = string.join(cipherList, '') |
| 43 | return cipherstring, int(R) |
| 44 | |
| 45 | |
| 46 | def hexString(s): |
jvr | d778713 | 2002-07-23 09:26:19 +0000 | [diff] [blame] | 47 | import binascii |
| 48 | return binascii.hexlify(s) |
Just | 6c53f88 | 2000-01-12 19:15:12 +0000 | [diff] [blame] | 49 | |
| 50 | def deHexString(h): |
jvr | d778713 | 2002-07-23 09:26:19 +0000 | [diff] [blame] | 51 | import binascii |
| 52 | h = "".join(h.split()) |
| 53 | return binascii.unhexlify(h) |
Just | 6c53f88 | 2000-01-12 19:15:12 +0000 | [diff] [blame] | 54 | |
| 55 | |
| 56 | def _test(): |
pabs3 | 0682316 | 2009-11-08 15:57:07 +0000 | [diff] [blame] | 57 | import fontTools.misc.eexecOp as eexecOp |
Just | 344757f | 2001-04-20 18:39:21 +0000 | [diff] [blame] | 58 | testStr = "\0\0asdadads asds\265" |
Just | 6c53f88 | 2000-01-12 19:15:12 +0000 | [diff] [blame] | 59 | print decrypt, decrypt(testStr, 12321) |
| 60 | print eexecOp.decrypt, eexecOp.decrypt(testStr, 12321) |
| 61 | print encrypt, encrypt(testStr, 12321) |
| 62 | print eexecOp.encrypt, eexecOp.encrypt(testStr, 12321) |
| 63 | |
| 64 | |
| 65 | if __name__ == "__main__": |
| 66 | _test() |
| 67 | |
| 68 | |
| 69 | try: |
pabs3 | 0682316 | 2009-11-08 15:57:07 +0000 | [diff] [blame] | 70 | from fontTools.misc.eexecOp import * |
Just | 6c53f88 | 2000-01-12 19:15:12 +0000 | [diff] [blame] | 71 | except ImportError: |
| 72 | pass # Use the slow Python versions |
| 73 | |