(self, recursive=True, overwrite=True, seed_hash=None)
Set "id" properties deterministically.

    An object's "id" property is set based on a hash of its class type and
    name, as well as the class type and name of all ancestor objects.  As
    such, it is only advisable to call ComputeIDs once an entire project file
    tree is built.

    If recursive is True, recurse into all descendant objects and update their
    hashes.

    If overwrite is True, any existing value set in the "id" property will be
    replaced.
Set "id" properties deterministically.
Set id properties deterministically .
def ComputeIDs(self, recursive=True, overwrite=True, seed_hash=None):
    """Set "id" properties deterministically.

    An object's "id" property is set based on a hash of its class type and
    name, as well as the class type and name of all ancestor objects.  As
    such, it is only advisable to call ComputeIDs once an entire project file
    tree is built.

    If recursive is True, recurse into all descendant objects and update their
    hashes.

    If overwrite is True, any existing value set in the "id" property will be
    replaced.
    """

    def _HashUpdate(hash, data):
      """Update hash with data's length and contents.

      If the hash were updated only with the value of data, it would be
      possible for clowns to induce collisions by manipulating the names of
      their objects.  By adding the length, it's exceedingly less likely that
      ID collisions will be encountered, intentionally or not.
      """

      hash.update(struct.pack('>i', len(data)))
      hash.update(data)

    if seed_hash is None:
      seed_hash = hashlib.sha1()

    hash = seed_hash.copy()

    hashables = self.Hashables()
    assert len(hashables) > 0
    for hashable in hashables:
      _HashUpdate(hash, hashable)

    if recursive:
      hashables_for_child = self.HashablesForChild()
      if hashables_for_child is None:
        child_hash = hash
      else:
        assert len(hashables_for_child) > 0
        child_hash = seed_hash.copy()
        for hashable in hashables_for_child:
          _HashUpdate(child_hash, hashable)

      for child in self.Children():
        child.ComputeIDs(recursive, overwrite, child_hash)

    if overwrite or self.id is None:
      # Xcode IDs are only 96 bits (24 hex characters), but a SHA-1 digest is
      # is 160 bits.  Instead of throwing out 64 bits of the digest, xor them
      # into the portion that gets used.
      assert hash.digest_size % 4 == 0
      digest_int_count = hash.digest_size / 4
      digest_ints = struct.unpack('>' + 'I' * digest_int_count, hash.digest())
      id_ints = [0, 0, 0]
      for index in range(0, digest_int_count):
        id_ints[index % 3] ^= digest_ints[index]
      self.id = '%08X%08X%08X' % tuple(id_ints)
def ComputeIDs ( self , recursive = True , overwrite = True , seed_hash = None ) : def _HashUpdate ( hash , data ) : """Update hash with data's length and contents.

      If the hash were updated only with the value of data, it would be
      possible for clowns to induce collisions by manipulating the names of
      their objects.  By adding the length, it's exceedingly less likely that
      ID collisions will be encountered, intentionally or not.
      """ hash . update ( struct . pack ( '>i' , len ( data ) ) ) hash . update ( data ) if seed_hash is None : seed_hash = hashlib . sha1 ( ) hash = seed_hash . copy ( ) hashables = self . Hashables ( ) assert len ( hashables ) > 0 for hashable in hashables : _HashUpdate ( hash , hashable ) if recursive : hashables_for_child = self . HashablesForChild ( ) if hashables_for_child is None : child_hash = hash else : assert len ( hashables_for_child ) > 0 child_hash = seed_hash . copy ( ) for hashable in hashables_for_child : _HashUpdate ( child_hash , hashable ) for child in self . Children ( ) : child . ComputeIDs ( recursive , overwrite , child_hash ) if overwrite or self . id is None : # Xcode IDs are only 96 bits (24 hex characters), but a SHA-1 digest is # is 160 bits.  Instead of throwing out 64 bits of the digest, xor them # into the portion that gets used. assert hash . digest_size % 4 == 0 digest_int_count = hash . digest_size / 4 digest_ints = struct . unpack ( '>' + 'I' * digest_int_count , hash . digest ( ) ) id_ints = [ 0 , 0 , 0 ] for index in range ( 0 , digest_int_count ) : id_ints [ index % 3 ] ^= digest_ints [ index ] self . id = '%08X%08X%08X' % tuple ( id_ints )