text: #!/usr/bin/python
  from __future__ import division
  
  import sys
  import bz2
  import string
  import hashlib
  
  try:
      import pefile
      HAVE_PEFILE = True
  except ImportError:
      HAVE_PEFILE = False
  
  try:
      import bitstring
      HAVE_BITSTRING = True
  except ImportError:
      HAVE_BITSTRING = False
  
  from viper.common.out import *
  
  def calculate_pehash(file_path=None):
      if not HAVE_PEFILE:
          print_error("Missing dependency, install pefile (`pip install pefile`)")
          return ''
  
      if not HAVE_BITSTRING:
          print_error("Missing dependency, install bitstring (`pip install bitstring`)")
          return ''
  
      if not file_path:
          return ''
  
      try:
          exe = pefile.PE(file_path)
      
          #image characteristics
          img_chars = bitstring.BitArray(hex(exe.FILE_HEADER.Characteristics))
          #pad to 16 bits
          img_chars = bitstring.BitArray(bytes=img_chars.tobytes())
          if img_chars.len == 16:
              img_chars_xor = img_chars[0:7] ^ img_chars[8:15]
          else:
              img_chars_xor = img_chars[0:7]
      
          #start to build pehash
          pehash_bin = bitstring.BitArray(img_chars_xor)
      
          #subsystem - 
          sub_chars = bitstring.BitArray(hex(exe.FILE_HEADER.Machine))
          #pad to 16 bits
          sub_chars = bitstring.BitArray(bytes=sub_chars.tobytes())
          sub_chars_xor = sub_chars[0:7] ^ sub_chars[8:15]
          pehash_bin.append(sub_chars_xor)
      
          #Stack Commit Size
          stk_size = bitstring.BitArray(hex(exe.OPTIONAL_HEADER.SizeOfStackCommit))
          stk_size_bits = string.zfill(stk_size.bin, 32)
          #now xor the bits
          stk_size = bitstring.BitArray(bin=stk_size_bits)
          stk_size_xor = stk_size[8:15] ^ stk_size[16:23] ^ stk_size[24:31]
          #pad to 8 bits
          stk_size_xor = bitstring.BitArray(bytes=stk_size_xor.tobytes())
          pehash_bin.append(stk_size_xor)
      
          #Heap Commit Size
          hp_size = bitstring.BitArray(hex(exe.OPTIONAL_HEADER.SizeOfHeapCommit))
          hp_size_bits = string.zfill(hp_size.bin, 32)
          #now xor the bits
          hp_size = bitstring.BitArray(bin=hp_size_bits)
          hp_size_xor = hp_size[8:15] ^ hp_size[16:23] ^ hp_size[24:31]
          #pad to 8 bits
          hp_size_xor = bitstring.BitArray(bytes=hp_size_xor.tobytes())
          pehash_bin.append(hp_size_xor)
      
          #Section chars
          for section in exe.sections:
              #virutal address
              sect_va =  bitstring.BitArray(hex(section.VirtualAddress))
              sect_va = bitstring.BitArray(bytes=sect_va.tobytes())
              pehash_bin.append(sect_va)    
      
              #rawsize
              sect_rs =  bitstring.BitArray(hex(section.SizeOfRawData))
              sect_rs = bitstring.BitArray(bytes=sect_rs.tobytes())
              sect_rs_bits = string.zfill(sect_rs.bin, 32)
              sect_rs = bitstring.BitArray(bin=sect_rs_bits)
              sect_rs = bitstring.BitArray(bytes=sect_rs.tobytes())
              sect_rs_bits = sect_rs[8:31]
              pehash_bin.append(sect_rs_bits)
      
              #section chars
              sect_chars =  bitstring.BitArray(hex(section.Characteristics))
              sect_chars = bitstring.BitArray(bytes=sect_chars.tobytes())
              sect_chars_xor = sect_chars[16:23] ^ sect_chars[24:31]
              pehash_bin.append(sect_chars_xor)
      
              #entropy calulation
              address = section.VirtualAddress
              size = section.SizeOfRawData
              raw = exe.write()[address+size:]
              if size == 0: 
                  kolmog = bitstring.BitArray(float=1, length=32)
                  pehash_bin.append(kolmog[0:7])
                  continue
              bz2_raw = bz2.compress(raw)
              bz2_size = len(bz2_raw)
              #k = round(bz2_size / size, 5)
              k = bz2_size / size
              kolmog = bitstring.BitArray(float=k, length=32)
              pehash_bin.append(kolmog[0:7])
      
          m = hashlib.sha1()
          m.update(pehash_bin.tobytes())
          return str(m.hexdigest())
      except:
          return ''
  