# Buggy code
def EqualityString(self):
    """Return a string describing the EventObject in terms of object equality.

    The details of this function must match the logic of __eq__. EqualityStrings
    of two event objects should be the same if and only if the EventObjects are
    equal as described in __eq__.

    Returns:
      String: will match another EventObject's Equality String if and only if
              the EventObjects are equal
    """
    fields = sorted(list(self.GetAttributes().difference(self.COMPARE_EXCLUDE)))

    # TODO: Review this (after 1.1.0 release). Is there a better/more clean
    # method of removing the timestamp description field out of the fields list?
    parser = getattr(self, "parser", "")
    if parser == "filestat":
        # We don't want to compare the timestamp description field when comparing
        # filestat events. This is done to be able to join together FILE events
        # that have the same timestamp, yet different description field (as in an
        # event that has for instance the same timestamp for mtime and atime,
        # joining it together into a single event).
        try:
            timestamp_desc_index = fields.index("timestamp_desc")
            del fields[timestamp_desc_index]
        except ValueError:
            pass

    basic = [self.timestamp, self.data_type]
    attributes = []
    for attribute in fields:
        value = getattr(self, attribute)
        if isinstance(value, dict):
            attributes.append(sorted(value.items()))
        elif isinstance(value, set):
            attributes.append(sorted(list(value)))
        else:
            attributes.append(value)
    identity = basic + [x for pair in zip(fields, attributes) for x in pair]

    if parser == "filestat":
        inode = getattr(self, "inode", "a")
        if inode == "a":
            inode = "_{0:s}".format(uuid.uuid4())
        identity.append("inode")
        identity.append(inode)

    return "|".join(map(unicode, identity))


# Traceback (UnicodeDecodeError)
[pe] Unable to process file: type: OS, location:<PATH>/test_images/win7-64-nfury-10.3.58.6/win7-64-nfury-c-drive/win7-64-nfury-c-drive.E01
type: EWF
type: TSK, inode: 75147, location: /Windows/assembly/NativeImages_v2.0.50727_32/UIAutomationClient/d0972fea9e965a565c3cff76982709db/UIAutomationClient.ni.dll
with error: 'ascii' codec can't decode byte 0x90 in position 7: ordinal not in range(128).

2015-06-02 10:40:54,309 [ERROR] (Worker_08 ) PID:16459 <worker> 'ascii' codec can't decode byte 0x90 in position 7: ordinal not in range(128)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/plaso-1.2.1_20150602-py2.7.egg/plaso/engine/worker.py", line 169, in _ParseFileEntryWithParser
File "/usr/local/lib/python2.7/dist-packages/plaso-1.2.1_20150602-py2.7.egg/plaso/parsers/interface.py", line 72, in UpdateChainAndParse
File "/usr/local/lib/python2.7/dist-packages/plaso-1.2.1_20150602-py2.7.egg/plaso/parsers/interface.py", line 256, in Parse
File "/usr/local/lib/python2.7/dist-packages/plaso-1.2.1_20150602-py2.7.egg/plaso/parsers/pe.py", line 259, in ParseFileObject
File "/usr/local/lib/python2.7/dist-packages/plaso-1.2.1_20150602-py2.7.egg/plaso/parsers/pe.py", line 132, in _GetSectionNames
UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 7: ordinal not in range(128)

# Fixed code
def EqualityString(self):
    """Return a string describing the EventObject in terms of object equality.

    The details of this function must match the logic of __eq__. EqualityStrings
    of two event objects should be the same if and only if the EventObjects are
    equal as described in __eq__.

    Returns:
      String: will match another EventObject's Equality String if and only if
              the EventObjects are equal
    """
    fields = sorted(list(self.GetAttributes().difference(self.COMPARE_EXCLUDE)))

    # TODO: Review this (after 1.1.0 release). Is there a better/more clean
    # method of removing the timestamp description field out of the fields list?
    parser = getattr(self, "parser", "")
    if parser == "filestat":
        # We don't want to compare the timestamp description field when comparing
        # filestat events. This is done to be able to join together FILE events
        # that have the same timestamp, yet different description field (as in an
        # event that has for instance the same timestamp for mtime and atime,
        # joining it together into a single event).
        try:
            timestamp_desc_index = fields.index("timestamp_desc")
            del fields[timestamp_desc_index]
        except ValueError:
            pass

    basic = [self.timestamp, self.data_type]
    attributes = []
    for attribute in fields:
        value = getattr(self, attribute)
        if isinstance(value, dict):
            attributes.append(sorted(value.items()))
        elif isinstance(value, set):
            attributes.append(sorted(list(value)))
        else:
            attributes.append(value)
    identity = basic + [x for pair in zip(fields, attributes) for x in pair]

    if parser == "filestat":
        inode = getattr(self, "inode", "a")
        if inode == "a":
            inode = "_{0:s}".format(uuid.uuid4())
        identity.append("inode")
        identity.append(inode)

    try:
        text = "|".join(map(unicode, identity))
        return text
    except UnicodeDecodeError:
        # If we cannot properly decode the equality string we give back the UUID
        # which is unique to this event and thus will not trigger an equal string
        # with another event.
        return self.uuid