#!/usr/bin/env python """ Python Character Mapping Codec for MS PST. The MS PST codec is used to encode PST files (outlook local storage files) using 'compressible encryption'. This is actually a simple substitution cipher. """ import codecs ### Codec APIs class Codec(codecs.Codec): def encode(self,input,errors='strict'): return codecs.charmap_encode(input,errors,encoding_map) def decode(self,input,errors='strict'): return codecs.charmap_decode(input,errors,decoding_map) class StreamWriter(Codec,codecs.StreamWriter): pass class StreamReader(Codec,codecs.StreamReader): pass ### Decoding Map ## The decoding map is a simple substitution cipher. decoding_map = codecs.make_identity_dict(range(256)) decoding_map.update( { 0: 71, 1: 241, 2: 180, 3: 230, 4: 11, 5: 106, 6: 114, 7: 72, 8: 133, 9: 78, 10: 158, 11: 235, 12: 226, 13: 248, 14: 148, 15: 83, 16: 224, 17: 187, 18: 160, 19: 2, 20: 232, 21: 90, 22: 9, 23: 171, 24: 219, 25: 227, 26: 186, 27: 198, 28: 124, 29: 195, 30: 16, 31: 221, 32: 57, 33: 5, 34: 150, 35: 48, 36: 245, 37: 55, 38: 96, 39: 130, 40: 140, 41: 201, 42: 19, 43: 74, 44: 107, 45: 29, 46: 243, 47: 251, 48: 143, 49: 38, 50: 151, 51: 202, 52: 145, 53: 23, 54: 1, 55: 196, 56: 50, 57: 45, 58: 110, 59: 49, 60: 149, 61: 255, 62: 217, 63: 35, 64: 209, 65: 0, 66: 94, 67: 121, 68: 220, 69: 68, 70: 59, 71: 26, 72: 40, 73: 197, 74: 97, 75: 87, 76: 32, 77: 144, 78: 61, 79: 131, 80: 185, 81: 67, 82: 190, 83: 103, 84: 210, 85: 70, 86: 66, 87: 118, 88: 192, 89: 109, 90: 91, 91: 126, 92: 178, 93: 15, 94: 22, 95: 41, 96: 60, 97: 169, 98: 3, 99: 84, 100: 13, 101: 218, 102: 93, 103: 223, 104: 246, 105: 183, 106: 199, 107: 98, 108: 205, 109: 141, 110: 6, 111: 211, 112: 105, 113: 92, 114: 134, 115: 214, 116: 20, 117: 247, 118: 165, 119: 102, 120: 117, 121: 172, 122: 177, 123: 233, 124: 69, 125: 33, 126: 112, 127: 12, 128: 135, 129: 159, 130: 116, 131: 164, 132: 34, 133: 76, 134: 111, 135: 191, 136: 31, 137: 86, 138: 170, 139: 46, 140: 179, 141: 120, 142: 51, 143: 80, 144: 176, 145: 163, 146: 146, 147: 188, 148: 207, 149: 25, 150: 28, 151: 167, 152: 99, 153: 203, 154: 30, 155: 77, 156: 62, 157: 75, 158: 27, 159: 155, 160: 79, 161: 231, 162: 240, 163: 238, 164: 173, 165: 58, 166: 181, 167: 89, 168: 4, 169: 234, 170: 64, 171: 85, 172: 37, 173: 81, 174: 229, 175: 122, 176: 137, 177: 56, 178: 104, 179: 82, 180: 123, 181: 252, 182: 39, 183: 174, 184: 215, 185: 189, 186: 250, 187: 7, 188: 244, 189: 204, 190: 142, 191: 95, 192: 239, 193: 53, 194: 156, 195: 132, 196: 43, 197: 21, 198: 213, 199: 119, 200: 52, 201: 73, 202: 182, 203: 18, 204: 10, 205: 127, 206: 113, 207: 136, 208: 253, 209: 157, 210: 24, 211: 65, 212: 125, 213: 147, 214: 216, 215: 88, 216: 44, 217: 206, 218: 254, 219: 36, 220: 175, 221: 222, 222: 184, 223: 54, 224: 200, 225: 161, 226: 128, 227: 166, 228: 153, 229: 152, 230: 168, 231: 47, 232: 14, 233: 129, 234: 101, 235: 115, 236: 228, 237: 194, 238: 162, 239: 138, 240: 212, 241: 225, 242: 17, 243: 208, 244: 8, 245: 139, 246: 42, 247: 242, 248: 237, 249: 154, 250: 100, 251: 63, 252: 193, 253: 108, 254: 249, 255: 236} ) ### Encoding Map encoding_map = codecs.make_encoding_map(decoding_map) def encode(input,errors='strict'): return codecs.charmap_encode(input,errors,encoding_map) def decode(input,errors='strict'): return codecs.charmap_decode(input,errors,decoding_map) def search_function(x): if x=='ms-pst': return (encode, decode, StreamReader, StreamWriter) ## This is required to be able to use the ms-pst encoding codecs.register(search_function)