def unpack(self, i): o, p = b'', 0 while p < len(i): # for python 3 must use slice since i[p] returns int while slice returns character c = ord(i[p:p + 1]) p += 1 if (c >= 1 and c <= 8): o += i[p:p + c] p += c elif (c < 128): o += bchr(c) elif (c >= 192): o += b' ' + bchr(c ^ 128) else: if p < len(i): c = (c << 8) | ord(i[p:p + 1]) p += 1 m = (c >> 3) & 0x07ff n = (c & 7) + 3 if (m > n): o += o[-m:n - m] else: for _ in range(n): # because of completely ass-backwards decision by python mainters for python 3 # we must use slice for bytes as i[p] returns int while slice returns character if m == 1: o += o[-m:] else: o += o[-m:-m + 1] return o
def Idpf_encryption_key(uid): # remove whitespace changing nothing else key = utf8_str(uid) key = key.replace(bchr(x20), b'') key = key.replace(bchr(x09), b'') key = key.replace(bchr(x0d), b'') key = key.replace(bchr(x0a), b'') key = SHA1(key) return key
def Idpf_encryption_key(uid): # remove whitespace changing nothing else key = utf8_str(uid) key = key.replace(bchr(0x20),b'') key = key.replace(bchr(0x09),b'') key = key.replace(bchr(0x0d),b'') key = key.replace(bchr(0x0a),b'') key = SHA1(key) return key
def Idpf_encryption_key(uid): # remove whitespace changing nothing else key = utf8_str(uid) if key.startswith(b"urn:uuid:"): key = key[9:] key = key.replace(bchr(0x20),b'') key = key.replace(bchr(0x09),b'') key = key.replace(bchr(0x0d),b'') key = key.replace(bchr(0x0a),b'') key = SHA1(key) return key
def Idpf_encryption_key(uid): # remove whitespace changing nothing else key = utf8_str(uid) if key.startswith(b"urn:uuid:"): key = key[9:] key = key.replace(bchr(0x20), b'') key = key.replace(bchr(0x09), b'') key = key.replace(bchr(0x0d), b'') key = key.replace(bchr(0x0a), b'') key = SHA1(key) return key
def Idpf_mangle_fonts(encryption_key, data): if isinstance(data, text_type): print('Error: font data must be a byte string') crypt = data[:1040] key = cycle(iter(map(bord, encryption_key))) encrypt = b''.join([bchr(bord(x) ^ next(key)) for x in crypt]) return encrypt + data[1040:]
def Idpf_mangle_fonts(encryption_key, data): if isinstance(data, text_type): print('Error: font data must be a byte string') crypt = data[:1040] key = cycle(iter(map(bord, encryption_key))) encrypt = b''.join([bchr(bord(x)^next(key)) for x in crypt]) return encrypt + data[1040:]
def getIndexData(self, idx, label="Unknown"): sect = self.sect outtbl = [] ctoc_text = {} if idx != 0xffffffff: sect.setsectiondescription(idx, "{0} Main INDX section".format(label)) data = sect.loadSection(idx) idxhdr, hordt1, hordt2 = self.parseINDXHeader(data) IndexCount = idxhdr['count'] # handle the case of multiple sections used for CTOC rec_off = 0 off = idx + IndexCount + 1 for j in range(idxhdr['nctoc']): cdata = sect.loadSection(off + j) sect.setsectiondescription(off + j, label + ' CTOC Data ' + str(j)) ctocdict = self.readCTOC(cdata) for k in ctocdict: ctoc_text[k + rec_off] = ctocdict[k] rec_off += 0x10000 tagSectionStart = idxhdr['len'] controlByteCount, tagTable = readTagSection(tagSectionStart, data) if self.DEBUG: print("ControlByteCount is", controlByteCount) print("IndexCount is", IndexCount) print("TagTable: %s" % tagTable) for i in range(idx + 1, idx + 1 + IndexCount): sect.setsectiondescription( i, "{0} Extra {1:d} INDX section".format(label, i - idx)) data = sect.loadSection(i) hdrinfo, ordt1, ordt2 = self.parseINDXHeader(data) idxtPos = hdrinfo['start'] entryCount = hdrinfo['count'] if self.DEBUG: print(idxtPos, entryCount) # loop through to build up the IDXT position starts idxPositions = [] for j in range(entryCount): pos, = struct.unpack_from(b'>H', data, idxtPos + 4 + (2 * j)) idxPositions.append(pos) # The last entry ends before the IDXT tag (but there might be zero fill bytes we need to ignore!) idxPositions.append(idxtPos) # for each entry in the IDXT build up the tagMap and any associated text for j in range(entryCount): startPos = idxPositions[j] endPos = idxPositions[j + 1] textLength = ord(data[startPos:startPos + 1]) text = data[startPos + 1:startPos + 1 + textLength] if hordt2 is not None: text = b''.join(bchr(hordt2[bord(x)]) for x in text) tagMap = getTagMap(controlByteCount, tagTable, data, startPos + 1 + textLength, endPos) outtbl.append([text, tagMap]) if self.DEBUG: print(tagMap) print(text) return outtbl, ctoc_text
def mangle_fonts(encryption_key, data): if isinstance(encryption_key, text_type): encryption_key = encryption_key.encode('latin-1') crypt = data[:1024] key = cycle(iter(map(bord, encryption_key))) # encrypt = ''.join([chr(ord(x)^key.next()) for x in crypt]) encrypt = b''.join([bchr(bord(x) ^ next(key)) for x in crypt]) return encrypt + data[1024:]
def applyInflectionRule(self, mainEntry, inflectionRuleData, start, end): ''' Apply inflection rule. @param mainEntry: The word to inflect. @param inflectionRuleData: The inflection rules. @param start: The start position of the inflection rule to use. @param end: The end position of the inflection rule to use. @return: The string with the inflected word or None if an error occurs. ''' mode = -1 byteArray = array.array(array_format, mainEntry) position = len(byteArray) for charOffset in range(start, end): char = inflectionRuleData[charOffset:charOffset + 1] abyte = ord(char) if abyte >= 0x0a and abyte <= 0x13: # Move cursor backwards offset = abyte - 0x0a if mode not in [0x02, 0x03]: mode = 0x02 position = len(byteArray) position -= offset elif abyte > 0x13: if mode == -1: print( "Error: Unexpected first byte %i of inflection rule" % abyte) return None elif position == -1: print( "Error: Unexpected first byte %i of inflection rule" % abyte) return None else: if mode == 0x01: # Insert at word start byteArray.insert(position, abyte) position += 1 elif mode == 0x02: # Insert at word end byteArray.insert(position, abyte) elif mode == 0x03: # Delete at word end position -= 1 deleted = byteArray.pop(position) if bchr(deleted) != char: if DEBUG_DICT: print("0x03: %s %s %s %s" % (mainEntry, toHex(inflectionRuleData[start:end]), char, bchr(deleted))) print( "Error: Delete operation of inflection rule failed" ) return None elif mode == 0x04: # Delete at word start deleted = byteArray.pop(position) if bchr(deleted) != char: if DEBUG_DICT: print("0x03: %s %s %s %s" % (mainEntry, toHex(inflectionRuleData[start:end]), char, bchr(deleted))) print( "Error: Delete operation of inflection rule failed" ) return None else: print( "Error: Inflection rule mode %x is not implemented" % mode) return None elif abyte == 0x01: # Insert at word start if mode not in [0x01, 0x04]: position = 0 mode = abyte elif abyte == 0x02: # Insert at word end if mode not in [0x02, 0x03]: position = len(byteArray) mode = abyte elif abyte == 0x03: # Delete at word end if mode not in [0x02, 0x03]: position = len(byteArray) mode = abyte elif abyte == 0x04: # Delete at word start if mode not in [0x01, 0x04]: position = 0 # Delete at word start mode = abyte else: print("Error: Inflection rule mode %x is not implemented" % abyte) return None return utf8_str(byteArray.tostring())