Ozcan Ozturk

119 papers A* 7A 22B 3C 7Misc 7Journal 36Unranked 37
YearRankTypeTitle / Venue / Authors
2026 J jnl
Frontiers Robotics AI
Melih Peker, Ozcan Ozturk
2026 J jnl
Future Gener. Comput. Syst.
Cemil Kaan Akyol, Muhammet Mustafa Ozdal, Ozcan Ozturk
2025 J jnl
CoRR
Naveed Ul Mustafa, Adrià Armejach, Ozcan Ozturk, Adrián Cristal, Osman S. Unsal
2024 B conf
ICPADS
Funda Atik, Serif Yesil, Hamza Ouarnoughi, Smaïl Niar, Ozcan Ozturk
2024 J jnl
IEEE Trans. Computers
Zülal Bingöl, Mohammed Alser, Onur Mutlu, Ozcan Ozturk, Can Alkan
2023 J jnl
Microprocess. Microsystems
Hamzeh Ahangari, Yusuf Ibrahim Ozkok, Asil Yildirim, Fatih Say, Funda Atik, Ozcan Ozturk
2023 conf
DSC
Tuncer Turhan, Hakan Tekgul, Ozcan Ozturk
2023 C conf
RSP
Melih Peker, Ozcan Ozturk
2023 J jnl
CoRR
Hadjer Benmeziane, Halima Bouzidi, Hamza Ouarnoughi, Ozcan Ozturk, Smaïl Niar
2023 C conf
DSD
Burak Ocalan, Ozcan Ozturk
2022 C conf
DSD
Erdem Derebasoglu, Ismail Kadayif, Ozcan Ozturk
2022 J jnl
ACM Trans. Design Autom. Electr. Syst.
Nihat Mert Cicek, Xipeng Shen, Ozcan Ozturk
2022 J jnl
IEEE Trans. Computers
Nihat Mert Cicek, Lin Ning, Ozcan Ozturk, Xipeng Shen
2022 J jnl
J. Supercomput.
Serif Yesil, Ozcan Ozturk
2022 J jnl
Computing
Ozcan Ozturk, Sabri Pllana, Smaïl Niar, Kaoutar El Maghraoui
2021 conf
IPDPS Workshops
Zülal Bingöl, Mohammed Alser, Onur Mutlu, Ozcan Ozturk, Can Alkan
2021 J jnl
CoRR
Zülal Bingöl, Mohammed Alser, Onur Mutlu, Ozcan Ozturk, Can Alkan
2021 J jnl
J. Supercomput.
Yigitcan Nalci, Pinar Kullu, Suleyman Tosun, Ozcan Ozturk
2020 J jnl
J. Real Time Image Process.
Naveed Ul Mustafa, Martin J. O'Riordan, Stephen Rogers, Ozcan Ozturk
2020 J jnl
IET Comput. Digit. Tech.
Ihsen Alouani, Hamzeh Ahangari, Ozcan Ozturk, Smaïl Niar
2020 C conf
PDP
Ayhan Demiriz, Hamzeh Ahangari, Ozcan Ozturk
2019 J jnl
Int. J. Parallel Program.
Ismail Akturk, Ozcan Ozturk
2019 conf
IPDPS Workshops
Ozcan Ozturk, Ben Glick, Jens Mache, David P. Bunde
2018 J jnl
IEEE Embed. Syst. Lett.
Ihsen Alouani, Hamzeh Ahangari, Ozcan Ozturk, Smaïl Niar
2018 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Andrey Ayupov, Serif Yesil, Muhammet Mustafa Ozdal, TaeMin Kim, Steven M. Burns, Ozcan Ozturk
2018 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Mohammadreza Soltaniyeh, Ismail Kadayif, Ozcan Ozturk
2017 J jnl
IEEE Micro
Muhammet Mustafa Ozdal, Serif Yesil, TaeMin Kim, Andrey Ayupov, John Greth, Steven M. Burns, Ozcan Ozturk
2017 J jnl
Microprocess. Microsystems
Arghavan Asad, Ozcan Ozturk, Mahmood Fathy, Mohammad Reza Jahed-Motlagh
2016 conf
RAPIDO@HiPEAC
Naveed Ul Mustafa, Ozcan Ozturk, Smaïl Niar
2016 conf
IDT
Ozcan Ozturk
2016 A ed.
ICS
Ozcan Ozturk, Kemal Ebcioglu, Mahmut T. Kandemir, Onur Mutlu
2015 A conf
ICCAD
Muhammet Mustafa Ozdal, Serif Yesil, TaeMin Kim, Andrey Ayupov, Steven M. Burns, Ozcan Ozturk
2015 C conf
DSD
Arghavan Asad, Ozcan Ozturk, Mahmood Fathy, Mohammad Reza Jahed-Motlagh
2015 A conf
ICCAD
Serif Yesil, Muhammet Mustafa Ozdal, TaeMin Kim, Andrey Ayupov, Steven M. Burns, Ozcan Ozturk
2015 conf
ISVLSI
Hamzeh Ahangari, Gulay Yalcin, Ozcan Ozturk, Osman S. Unsal, Adrián Cristal
2014 conf
ICPP Workshops
Mert Emin Kalender, Cem Mergenci, Ozcan Ozturk
2013 J jnl
IEEE Trans. Computers
Ozcan Ozturk, Mahmut T. Kandemir, Guangyu Chen
2013 J jnl
ACM Trans. Design Autom. Electr. Syst.
Ismail Kadayif, Mahir Turkcan, Seher Kiziltepe, Ozcan Ozturk
2013 C conf
PDP
Ismail Akturk, Ozcan Ozturk
2013 J jnl
Parallel Comput.
Omer Erdil Albayrak, Ismail Akturk, Ozcan Ozturk
2013 J jnl
J. Electron. Test.
Ismail Akturk, Ozcan Ozturk
2013 C conf
VLSI-SoC
Melvin Eze, Ozcan Ozturk, Vijaykrishnan Narayanan
2012 conf
ICPP Workshops
Omer Erdil Albayrak, Ismail Akturk, Ozcan Ozturk
2011 J jnl
J. Parallel Distributed Comput.
Ozcan Ozturk
2011 J jnl
IEEE Trans. Educ.
Ozcan Ozturk
2011 J jnl
Comput. Lang. Syst. Struct.
Ozcan Ozturk
2010 conf
Euro-Par (1)
Taylan Yemliha, Mahmut T. Kandemir, Ozcan Ozturk, Emre Kultursay, Sai Prashanth Muralidhara
2010 B conf
LCTES
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin, Sri Hari Krishna Narayanan
2010 J jnl
Comput. Electr. Eng.
Ozcan Ozturk
2010 J jnl
IET Comput. Digit. Tech.
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin
2009 A conf
DATE
Mahmut T. Kandemir, Yuanrui Zhang, Ozcan Ozturk
2009 A* conf
DAC
Mahmut T. Kandemir, Ozcan Ozturk, Sai Prashanth Muralidhara
2009 conf
MSE
Ozcan Ozturk
2009 conf
LCPC
Boubacar Diouf, Ozcan Ozturk, Albert Cohen
2009 A* conf
MICRO
Mahmut T. Kandemir, Sai Prashanth Muralidhara, Sri Hari Krishna Narayanan, Yuanrui Zhang, Ozcan Ozturk
2009 A conf
DATE
Shengyan Hong, Sri Hari Krishna Narayanan, Mahmut T. Kandemir, Ozcan Ozturk
2009 J jnl
Int. J. Embed. Syst.
Ozcan Ozturk, Mahmut T. Kandemir, Seung Woo Son, Ibrahim Kolcu
2009 Misc conf
CASES
Mahmut T. Kandemir, Yuanrui Zhang, Sai Prashanth Muralidhara, Ozcan Ozturk, Sri Hari Krishna Narayanan
2009 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin
2009 A conf
DATE
Ozcan Ozturk, Mahmut T. Kandemir
2008 conf
ISQED
Ozcan Ozturk, Mahmut T. Kandemir, Sri Hari Krishna Narayanan
2008 J jnl
ACM Trans. Design Autom. Electr. Syst.
Ozcan Ozturk, Mahmut T. Kandemir, Guangyu Chen
2008 J jnl
ACM Trans. Design Autom. Electr. Syst.
Ozcan Ozturk, Mahmut T. Kandemir
2008 A conf
SC
Ozcan Ozturk, Seung Woo Son, Mahmut T. Kandemir, Mustafa Karaköy
2008 B conf
PACT
Seung Woo Son, Sai Prashanth Muralidhara, Ozcan Ozturk, Mahmut T. Kandemir, Ibrahim Kolcu, Mustafa Karaköy
2008 A conf
ICCAD
Taylan Yemliha, Shekhar Srikantaiah, Mahmut T. Kandemir, Ozcan Ozturk
2008 A* conf
SIGMETRICS
Mahmut T. Kandemir, Ozcan Ozturk
2007 A* conf
DAC
Liping Xue, Ozcan Ozturk, Mahmut T. Kandemir
2007 Misc conf
VLSI Design
Feihui Li, Guilin Chen, Mahmut T. Kandemir, Ozcan Ozturk, Mustafa Karaköy, Rajaraman Ramanarayanan, Balaji Vaidyanathan
2007 J jnl
CoRR
Ozcan Ozturk, Hendra Saputra, Mahmut T. Kandemir, Ibrahim Kolcu
2007 A conf
ISLPED
Ozcan Ozturk, Mahmut T. Kandemir, Seung Woo Son
2007 Misc conf
VLSI Design
Taylan Yemliha, Guangyu Chen, Ozcan Ozturk, Mahmut T. Kandemir, Vijay Degalahal
2007 J jnl
IEEE Trans. Parallel Distributed Syst.
Seung Woo Son, Guangyu Chen, Ozcan Ozturk, Mahmut T. Kandemir, Alok N. Choudhary
2007 A conf
CGO
Ozcan Ozturk, Guilin Chen, Mahmut T. Kandemir, Mustafa Karaköy
2007 Misc conf
VLSI Design
Mahmut T. Kandemir, Ozcan Ozturk, Vijay Degalahal
2007 Misc conf
VLSI Design
Liping Xue, Mahmut T. Kandemir, Guilin Chen, Feihui Li, Ozcan Ozturk, Rajaraman Ramanarayanan, Balaji Vaidyanathan
2007 A conf
DATE
Mahmut T. Kandemir, Taylan Yemliha, Seung Woo Son, Ozcan Ozturk
2007 A* conf
DAC
Hakduran Koc, Mahmut T. Kandemir, Ehat Ercanli, Ozcan Ozturk
2006 conf
ISCIS
Suleyman Tosun, Nazanin Mansouri, Mahmut T. Kandemir, Ozcan Ozturk
2006 conf
ACM Great Lakes Symposium on VLSI
Ozcan Ozturk, Mahmut T. Kandemir, Suleyman Tosun
2006 conf
ISVLSI
Ozcan Ozturk, G. Chen, Mahmut T. Kandemir, Mustafa Karaköy
2006 A conf
ICCAD
Ozcan Ozturk, G. Chen, Mahmut T. Kandemir, Mustafa Karaköy
2006 conf
ISVLSI
Guangyu Chen, Feihui Li, Mahmut T. Kandemir, Ozcan Ozturk, I. Demirkiran
2006 conf
ISQED
Sri Hari Krishna Narayanan, Mahmut T. Kandemir, Ozcan Ozturk
2006 conf
ASP-DAC
Ozcan Ozturk, Guangyu Chen, Mahmut T. Kandemir, Ibrahim Kolcu
2006 conf
ISQED
Ozcan Ozturk, Mahmut T. Kandemir
2006 A conf
DATE
Liping Xue, Ozcan Ozturk, Feihui Li, Mahmut T. Kandemir, Ibrahim Kolcu
2006 A conf
DATE
Guilin Chen, Ozcan Ozturk, Mahmut T. Kandemir, Mustafa Karaköy
2006 conf
SoCC
Guilin Chen, Ozcan Ozturk, Guangyu Chen, Mahmut T. Kandemir
2006 conf
ISVLSI
Guangyu Chen, Feihui Li, Ozcan Ozturk, Guilin Chen, Mahmut T. Kandemir, Ibrahim Kolcu
2006 A conf
ISLPED
Hakduran Koc, Ozcan Ozturk, Mahmut T. Kandemir, Sri Hari Krishna Narayanan, Ehat Ercanli
2006 conf
ICPADS (1)
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin, Suleyman Tosun
2006 conf
Conf. Computing Frontiers
Ozcan Ozturk, Guangyu Chen, Mahmut T. Kandemir
2006 conf
ASP-DAC
Ozcan Ozturk, Feng Wang, Mahmut T. Kandemir, Yuan Xie
2006 A* conf
DAC
Ozcan Ozturk, Guilin Chen, Mahmut T. Kandemir
2006 conf
ISVLSI
Hakduran Koc, Suleyman Tosun, Ozcan Ozturk, Mahmut T. Kandemir
2006 conf
ACM Great Lakes Symposium on VLSI
Ozcan Ozturk, Mahmut T. Kandemir, Seung Woo Son, Mustafa Karaköy
2006 conf
ISQED
Ozcan Ozturk, Mahmut T. Kandemir, Ibrahim Kolcu
2005 conf
ISVLSI
Hendra Saputra, Ozcan Ozturk, Narayanan Vijaykrishnan, Mahmut T. Kandemir, Richard R. Brooks
2005 A conf
DATE
Ozcan Ozturk, Hendra Saputra, Mahmut T. Kandemir, Ibrahim Kolcu
2005 A conf
IEEE Real-Time and Embedded Technology and Applications Symposium
Guilin Chen, Guangyu Chen, Ozcan Ozturk, Mahmut T. Kandemir
2005 conf
ISQED
Suleyman Tosun, Ozcan Ozturk, Nazanin Mansouri, Ercument Arvas, Mahmut T. Kandemir, Yuan Xie, Wei-Lun Hung
2005 A conf
DATE
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin
2005 conf
ASP-DAC
Ozcan Ozturk, Mahmut T. Kandemir, G. Chen, Mary Jane Irwin, Mustafa Karaköy
2005 conf
ACM Great Lakes Symposium on VLSI
Ozcan Ozturk, Mahmut T. Kandemir
2005 conf
ISVLSI
Guilin Chen, Guangyu Chen, Ozcan Ozturk, Mahmut T. Kandemir
2005 A conf
DATE
Gokhan Memik, Mahmut T. Kandemir, Ozcan Ozturk
2005 Misc conf
CODES+ISSS
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin
2005 conf
ACM Great Lakes Symposium on VLSI
Ozcan Ozturk, Mahmut T. Kandemir
2005 A conf
ICCAD
Guilin Chen, Ozcan Ozturk, Mahmut T. Kandemir, Ibrahim Kolcu
2005 A conf
DATE
Ozcan Ozturk, Mahmut T. Kandemir
2005 J jnl
IEEE Trans. Parallel Distributed Syst.
Ismail Kadayif, Mahmut T. Kandemir, Guilin Chen, Ozcan Ozturk, Mustafa Karaköy, Ugur Sezer
2005 A conf
DATE
Mahmut T. Kandemir, Feihui Li, Guilin Chen, Guangyu Chen, Ozcan Ozturk
2005 conf
ACM Great Lakes Symposium on VLSI
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin
2004 conf
LCPC
Guilin Chen, Ozcan Ozturk, Mahmut T. Kandemir
2004 A* conf
DAC
Ozcan Ozturk, Mahmut T. Kandemir, I. Demirkiran, Guangyu Chen, Mary Jane Irwin
2004 Misc conf
CASES
Mahmut T. Kandemir, Ozcan Ozturk, Mustafa Karaköy
2004 conf
ACM Great Lakes Symposium on VLSI
Ozcan Ozturk, Mahmut T. Kandemir, Mary Jane Irwin, Ibrahim Kolcu
2004 conf
Euro-Par
Mahmut T. Kandemir, Ozcan Ozturk, Mary Jane Irwin, Ibrahim Kolcu
redb/extractors/hashes.py
← Index redb/extractors/hashes.py python
from dataclasses import asdict
from typing import Any
from datetime import datetime, timezone

import hashlib
import inspect
from struct import pack

from magika import Magika
from signify.fingerprinter import AuthenticodeFingerprinter
import ppdeep
import tlsh

import pefile
from elftools.elf.elffile import ELFFile
from elftools.common.exceptions import ELFError

from redb.extractors.enum import Tag
from redb.models.dataclasses import Hashes
from redb.extractors.extractor import Extractor


class HashExtractor(Extractor):

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
        macho=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix, elastic_index, known_benign, known_malicious
        )
        self.hashes = None
        self.elastic_index = self.index_prefix + "-hashes"
        self.filetype = Magika().identify_bytes(self.binary).output.label
        self.pe = None
        self.elf = None
        self.macho = macho
        if self.filetype == "pebin":  # else None
            try:
                self.pe = pefile.PE(self.filepath)
            except Exception as e:
                self.log.error(f"Failed to initialize PE file object: {e}")
                self.pe = None
        elif self.filetype == "elf":
            # ELF file will be created when needed in _extract_elf_hashes
            pass

    def _extract_hashes(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        
        # Initialize hash values with None
        md5 = None
        sha1 = None
        sha256 = None
        ssdeep_hash = None
        tlsh_hash = None
        
        # Calculate basic hashes with error handling
        try:
            md5 = hashlib.md5(self.binary).hexdigest()
        except Exception as e:
            self.log.error(f"Failed to calculate MD5 hash: {e}")
            
        try:
            sha1 = hashlib.sha1(self.binary).hexdigest()
        except Exception as e:
            self.log.error(f"Failed to calculate SHA1 hash: {e}")
            
        try:
            sha256 = hashlib.sha256(self.binary).hexdigest()
        except Exception as e:
            self.log.error(f"Failed to calculate SHA256 hash: {e}")
            
        try:
            ssdeep_hash = ppdeep.hash_from_file(self.filepath)
        except Exception as e:
            self.log.error(f"Failed to calculate ssdeep hash: {e}")
            
        try:
            tlsh_hash = tlsh.hash(self.binary)
        except Exception as e:
            self.log.error(f"Failed to calculate TLSH hash: {e}")
        
        # Create Hashes object with available values
        self.hashes = Hashes(
            md5 or "",
            sha1 or "",
            sha256 or "",
            ssdeep_hash or "",
            tlsh_hash or "",
        )

        if self.filetype == "pebin" and self.pe is not None:
            self.log.debug("Computing PEBIN related hash values")
            
            # Authentihash
            try:
                with open(self.filepath, 'rb') as f:
                    fingerprinter = AuthenticodeFingerprinter(f)
                    fingerprinter.add_authenticode_hashers(hashlib.sha256)
                    self.hashes.authentihash = fingerprinter.hash()['sha256'].hex()
            except Exception as e:
                self.log.error(f"Failed to calculate Authentihash: {e}")
                self.hashes.authentihash = None
                
            # Imphash
            try:
                self.hashes.imphash = self.pe.get_imphash()
            except Exception as e:
                self.log.error(f"Failed to calculate Imphash: {e}")
                self.hashes.imphash = None
                
            # Rich header hashes
            try:
                if self.pe.parse_rich_header():
                    self.log.debug("Computing RichHeader related hash values")
                    
                    richhash = self._compute_richhash()
                    if richhash:
                        self.hashes.richhash = richhash
                        
                    richpe_hash = self._compute_richpe_hash()
                    if richpe_hash:
                        self.hashes.richpe_hash = richpe_hash
                        
                    richpv_result = self._compute_richpv_hash()
                    if richpv_result:
                        self.hashes.richpv_hash, self.hashes.richpv_hash_sorted = richpv_result
            except Exception as e:
                self.log.error(f"Failed to calculate Rich header hashes: {e}")
        elif self.filetype == "pebin" and self.pe is None:
            self.log.warning("PE file type detected but PE object initialization failed - skipping PE-specific hashes")

        elif self.filetype == "elf":
            self.log.debug("Computing ELF related hash values")
            self._extract_elf_hashes()
        elif self.filetype == "macho":
            self.log.debug("Computing Mach-O related hash values")
            self._extract_macho_hashes()
        elif self.filetype == "apk":
            self.log.debug("Computing APK related hash values")
            self._extract_apk_hashes()
        else:
            pass
        self.log.debug(f"Hashes dump: {asdict(self.hashes)}")
        return self.hashes

    def _compute_richhash(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            rich_header = self.pe.parse_rich_header()
            if not rich_header:
                return ""
            data = rich_header["clear_data"]
            return hashlib.md5(data).hexdigest().lower()
        except:
            return ""

    def _compute_richpe_hash(self):
        """
        Computes the RichPE hash given a file path or PE object.

        RichPE hash is includes RichHeader CompID and count, as well as
        fields from IMAGE_FILE_HEADER and IMAGE_OPTIONAL_HEADER

        Parameters:
        input: it can be either a file path or a PE object

        Returns:
        richpe_hash: md5 hash of the RichPE value
        None: if no Rich Header present
        """
        try:
            # Attempt to parse Rich header
            self.log.debug(inspect.currentframe().f_code.co_name)
            rich_header = self.pe.parse_rich_header()
            if rich_header is None:
                return None

            # Get list of @Comp.IDs and counts from Rich header
            # Elements in rich_fields at even indices are @Comp.IDs
            # Elements in rich_fields at odd indices are counts
            rich_fields = rich_header.get("values", None)
            if not rich_fields or len(rich_fields) % 2 != 0:
                return None

            md5 = hashlib.md5()

            # Update hash using @Comp.IDs and masked counts from Rich header
            while len(rich_fields):
                compid = rich_fields.pop(0)
                count = rich_fields.pop(0)
                mask = 2 ** (count.bit_length() // 2 + 1) - 1
                count |= mask
                md5.update(pack("<L", compid))
                md5.update(pack("<L", count))

            # Update hash using metadata from the PE header
            md5.update(pack("<L", self.pe.FILE_HEADER.Machine))
            md5.update(pack("<L", self.pe.FILE_HEADER.Characteristics))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.Subsystem))
            md5.update(pack("<B", self.pe.OPTIONAL_HEADER.MajorLinkerVersion))
            md5.update(pack("<B", self.pe.OPTIONAL_HEADER.MinorLinkerVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MajorOperatingSystemVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MinorOperatingSystemVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MajorImageVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MinorImageVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MajorSubsystemVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MinorSubsystemVersion))

            return md5.hexdigest()
        except Exception as e:
            self.log.error(f"Failed to compute RichPE hash: {e}")
            return None

    def _compute_richpv_hash(self):
        """
        Compute the RichPV hash values, sorted and unsorted.
        RichPV excludes the most volatile Rich Header field from the MD5 input data,
        the Product Count (pC) field.

        Returns:
        richpv_hash_unsorted: md5 hash of the RichPV value unsorted
        richpv_hash_sorted: md5 hash of the RichPV value sorted
        None: if no Rich Header present
        """
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)
            # Attempt to parse Rich header
            rich_header = self.pe.parse_rich_header()
            if rich_header is None:
                return None

            # Get list of @Comp.IDs and counts from Rich header
            # Elements in rich_fields at even indices are @Comp.IDs
            # Elements in rich_fields at odd indices are counts
            rich_fields = rich_header.get("values", None)
            if not rich_fields or len(rich_fields) % 2 != 0:
                return None

            md5 = hashlib.md5()
            md5_sorted = hashlib.md5()
            sorted_vector = []

            # Update hash using @Comp.IDs only
            for i in range(0, len(rich_fields), 2):
                compid = rich_fields[i]
                md5.update(pack("<L", compid))
                sorted_vector.append(compid)

            sorted_vector.sort()
            for compid in sorted_vector:
                md5_sorted.update(pack("<L", compid))

            return md5.hexdigest(), md5_sorted.hexdigest()
        except Exception as e:
            self.log.error(f"Failed to compute RichPV hash: {e}")
            return None

    def _extract_elf_hashes(self):
        """Extract ELF specific similarity hashes."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        try:
            with open(self.filepath, 'rb') as f:
                elf = ELFFile(f)
                if not elf:
                    return

                # Generate all similarity hashes
                import_hash = self._generate_elf_import_hash(elf)
                export_hash = self._generate_elf_export_hash(elf)
                section_hash = self._generate_elf_section_hash(elf)
                symbol_hash = self._generate_elf_symbol_hash(elf)
                dynamic_hash = self._generate_elf_dynamic_hash(elf)

                # Only set hashes if they have meaningful values
                if import_hash:
                    self.hashes.import_hash = import_hash
                if export_hash:
                    self.hashes.export_hash = export_hash
                if section_hash:
                    self.hashes.section_hash = section_hash
                if symbol_hash:
                    self.hashes.symhash = symbol_hash
                if dynamic_hash:
                    self.hashes.dynamic_hash = dynamic_hash

        except Exception as e:
            self.log.error(f"Failed to extract ELF hashes: {e}")

    def _generate_elf_import_hash(self, elf) -> str:
        """Generate MD5 hash of sorted, deduplicated imported symbol names."""
        try:
            imported_symbols = set()

            # Get dynamic symbol table
            dynsym_section = elf.get_section_by_name('.dynsym')
            if dynsym_section and hasattr(dynsym_section, 'iter_symbols'):
                for symbol in dynsym_section.iter_symbols():
                    # Look for undefined symbols (imports)
                    if (symbol.entry.get('st_shndx', 0) == 'SHN_UNDEF' and
                        symbol.name and
                        symbol.entry.get('st_info', {}).get('bind') in ['STB_GLOBAL', 'STB_WEAK']):
                        imported_symbols.add(symbol.name)

            # Also check relocations for additional imports
            for section in elf.iter_sections():
                if hasattr(section, 'iter_relocations'):
                    try:
                        for relocation in section.iter_relocations():
                            if hasattr(relocation, 'symbol') and relocation.symbol and relocation.symbol.name:
                                imported_symbols.add(relocation.symbol.name)
                    except:
                        pass

            # Sort and concatenate
            sorted_imports = sorted(list(imported_symbols))

            # Return None if no imports found
            if not sorted_imports:
                return None

            imports_string = '|'.join(sorted_imports)

            # Generate MD5 hash
            return hashlib.md5(imports_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF import hash: {e}")
            return None

    def _generate_elf_export_hash(self, elf) -> str:
        """Generate MD5 hash of sorted, deduplicated exported symbol names."""
        try:
            exported_symbols = set()

            # Check both static and dynamic symbol tables
            symbol_sections = ['.symtab', '.dynsym']

            for section_name in symbol_sections:
                section = elf.get_section_by_name(section_name)
                if not section or not hasattr(section, 'iter_symbols'):
                    continue

                for symbol in section.iter_symbols():
                    # Check if symbol is exported (defined and globally visible)
                    if (symbol.name and
                        symbol.entry.get('st_shndx', 0) != 'SHN_UNDEF' and
                        symbol.entry.get('st_info', {}).get('bind') in ['STB_GLOBAL', 'STB_WEAK'] and
                        symbol.entry.get('st_info', {}).get('type') in ['STT_FUNC', 'STT_OBJECT']):
                        exported_symbols.add(symbol.name)

            # Sort and concatenate
            sorted_exports = sorted(list(exported_symbols))

            # Return None if no exports found
            if not sorted_exports:
                return None

            exports_string = '|'.join(sorted_exports)

            # Generate MD5 hash
            return hashlib.md5(exports_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF export hash: {e}")
            return None

    def _generate_elf_section_hash(self, elf) -> str:
        """Generate MD5 hash of section layout (names, types, flags sequence)."""
        try:
            section_info = []

            for section in elf.iter_sections():
                header = section.header
                section_name = section.name or "<unnamed>"
                section_type = header.get('sh_type', 'SHT_NULL')
                section_flags = header.get('sh_flags', 0)

                # Create a consistent representation
                section_repr = f"{section_name}:{section_type}:{section_flags}"
                section_info.append(section_repr)

            # Return None if no meaningful sections found
            if not section_info:
                return None

            # Join all section info
            sections_string = '|'.join(section_info)

            # Generate MD5 hash
            return hashlib.md5(sections_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF section hash: {e}")
            return None

    def _generate_elf_symbol_hash(self, elf) -> str:
        """Generate MD5 hash of sorted symbol names and types."""
        try:
            symbol_info = set()

            # Check both static and dynamic symbol tables
            symbol_sections = ['.symtab', '.dynsym']

            for section_name in symbol_sections:
                section = elf.get_section_by_name(section_name)
                if not section or not hasattr(section, 'iter_symbols'):
                    continue

                for symbol in section.iter_symbols():
                    if symbol.name:
                        symbol_type = symbol.entry.get('st_info', {}).get('type', 'STT_NOTYPE')
                        symbol_bind = symbol.entry.get('st_info', {}).get('bind', 'STB_LOCAL')

                        # Create a consistent representation
                        symbol_repr = f"{symbol.name}:{symbol_type}:{symbol_bind}"
                        symbol_info.add(symbol_repr)

            # Sort and concatenate
            sorted_symbols = sorted(list(symbol_info))

            # Return None if no symbols found
            if not sorted_symbols:
                return None

            symbols_string = '|'.join(sorted_symbols)

            # Generate MD5 hash
            return hashlib.md5(symbols_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF symbol hash: {e}")
            return None

    def _generate_elf_dynamic_hash(self, elf) -> str:
        """Generate MD5 hash of dynamic section entries (DT_* tags)."""
        try:
            dynamic_info = []

            # Get the dynamic section
            dynamic_section = elf.get_section_by_name('.dynamic')
            if not dynamic_section:
                return None

            # Extract dynamic tags and their values
            for tag in dynamic_section.iter_tags():
                dt_tag = tag.entry.d_tag

                # Create a representation based on tag type
                if dt_tag == 'DT_NEEDED':
                    dynamic_info.append(f"DT_NEEDED:{tag.needed}")
                elif dt_tag == 'DT_SONAME':
                    dynamic_info.append(f"DT_SONAME:{tag.soname}")
                elif dt_tag == 'DT_RPATH':
                    dynamic_info.append(f"DT_RPATH:{tag.rpath}")
                elif dt_tag == 'DT_RUNPATH':
                    dynamic_info.append(f"DT_RUNPATH:{tag.runpath}")
                else:
                    # For other tags, use the tag name and value
                    dt_value = tag.entry.d_val if hasattr(tag.entry, 'd_val') else 0
                    dynamic_info.append(f"{dt_tag}:{dt_value}")

            # Sort to ensure consistent ordering
            dynamic_info.sort()
            dynamics_string = '|'.join(dynamic_info)

            # Generate MD5 hash
            return hashlib.md5(dynamics_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF dynamic hash: {e}")
            return None

    def _extract_macho_hashes(self):
        """Extract Mach-O specific similarity hashes using machofile API.

        For FAT binaries, this extracts hashes for the current file being processed
        (either the FAT container or an individual slice). The machofile library
        handles the architecture-specific extraction when an arch parameter is provided.

        For slices: We parse the slice file directly since it's a standalone Mach-O.
        For FAT container: We use the provided macho object with combined/fat hashes.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        try:
            # If we have a pre-parsed macho object (FAT container or single-arch with passed object)
            if self.macho:
                architectures = self.macho.get_architectures()
                is_fat = len(architectures) > 1

                if is_fat:
                    # For FAT container, get combined hashes (key may be 'fat' or 'combined')
                    all_hashes = self.macho.get_similarity_hashes()
                    if all_hashes:
                        # Try 'fat' first, then 'combined' for backwards compatibility
                        similarity_hashes = all_hashes.get('fat', all_hashes.get('combined', {}))
                    else:
                        similarity_hashes = {}
                else:
                    # Single-arch with pre-parsed object
                    similarity_hashes = self.macho.get_similarity_hashes(arch=architectures[0]) if architectures else {}
            else:
                # No pre-parsed object - parse the file (slice case)
                import machofile
                macho = machofile.UniversalMachO(self.filepath)
                macho.parse()

                architectures = macho.get_architectures()
                if architectures:
                    # For a slice, there's only one architecture
                    similarity_hashes = macho.get_similarity_hashes(arch=architectures[0]) or {}
                else:
                    similarity_hashes = {}

            # Set the hash values on the Hashes object
            if similarity_hashes:
                if similarity_hashes.get('dylib_hash'):
                    self.hashes.macho_dylib_hash = similarity_hashes['dylib_hash']
                if similarity_hashes.get('import_hash'):
                    self.hashes.macho_import_hash = similarity_hashes['import_hash']
                if similarity_hashes.get('export_hash'):
                    self.hashes.macho_export_hash = similarity_hashes['export_hash']
                if similarity_hashes.get('entitlement_hash'):
                    self.hashes.macho_entitlement_hash = similarity_hashes['entitlement_hash']
                if similarity_hashes.get('symhash'):
                    self.hashes.macho_symhash = similarity_hashes['symhash']

        except Exception as e:
            self.log.error(f"Failed to extract Mach-O hashes: {e}")

    def _extract_apk_hashes(self):
        """Extract APK specific similarity hashes (permhash)."""
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            from permhash.functions import permhash_apk
            ph = permhash_apk(self.filepath)
            if ph:
                self.hashes.permhash = ph
        except Exception as e:
            self.log.error(f"Failed to extract APK hashes: {e}")

    def extract(self):
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)
            self._extract_hashes()
            return self.hashes
        except Exception as e:
            self.log.error(f"Error extracting hashes: {e}")
            return None

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ElasticsearchExporter":
            return self.hashes
        elif exporter_type == "ClickHouseExporter":
            # Safely get hash values with fallbacks for None values
            sha256 = getattr(self.hashes, 'sha256', None) or ""
            md5 = getattr(self.hashes, 'md5', None) or ""
            sha1 = getattr(self.hashes, 'sha1', None) or ""
            ssdeep_hash = getattr(self.hashes, 'ssdeep_hash', None) or ""
            tlsh_hash = getattr(self.hashes, 'tlsh_hash', None) or ""
            authentihash = getattr(self.hashes, 'authentihash', None)
            imphash = getattr(self.hashes, 'imphash', None)
            impfuzzy = getattr(self.hashes, 'impfuzzy', None)
            typerefhash = getattr(self.hashes, 'typerefhash', None)
            richhash = getattr(self.hashes, 'richhash', None)
            richpe_hash = getattr(self.hashes, 'richpe_hash', None)
            richpv_hash = getattr(self.hashes, 'richpv_hash', None)
            richpv_hash_sorted = getattr(self.hashes, 'richpv_hash_sorted', None)
            # ELF hashes
            import_hash = getattr(self.hashes, 'import_hash', None)
            export_hash = getattr(self.hashes, 'export_hash', None)
            section_hash = getattr(self.hashes, 'section_hash', None)
            symbol_hash = getattr(self.hashes, 'symhash', None)
            dynamic_hash = getattr(self.hashes, 'dynamic_hash', None)
            # Mach-O hashes
            macho_dylib_hash = getattr(self.hashes, 'macho_dylib_hash', None)
            macho_import_hash = getattr(self.hashes, 'macho_import_hash', None)
            macho_export_hash = getattr(self.hashes, 'macho_export_hash', None)
            macho_entitlement_hash = getattr(self.hashes, 'macho_entitlement_hash', None)
            macho_symhash = getattr(self.hashes, 'macho_symhash', None)
            # APK hashes
            permhash = getattr(self.hashes, 'permhash', None)

            data = [[
                sha256,
                md5,
                sha1,
                ssdeep_hash,
                tlsh_hash,
                authentihash,
                imphash,
                impfuzzy,
                typerefhash,
                richhash,
                richpe_hash,
                richpv_hash,
                richpv_hash_sorted,
                import_hash,
                export_hash,
                section_hash,
                symbol_hash,
                dynamic_hash,
                macho_dylib_hash,
                macho_import_hash,
                macho_export_hash,
                macho_entitlement_hash,
                macho_symhash,
                permhash,
                datetime.now(timezone.utc)
            ]]

            column_names = [
                'sha256', 'md5', 'sha1', 'ssdeep_hash', 'tlsh_hash',
                'authentihash', 'imphash', 'impfuzzy', 'typerefhash',
                'richhash', 'richpe_hash', 'richpv_hash', 'richpv_hash_sorted',
                'import_hash', 'export_hash', 'section_hash', 'symbol_hash', 'dynamic_hash',
                'macho_dylib_hash', 'macho_import_hash', 'macho_export_hash',
                'macho_entitlement_hash', 'macho_symhash',
                'permhash',
                'analysis_date'
            ]

            column_type_names = [
                # sha256, md5, sha1
                'String', 'String', 'String',
                # ssdeep_hash, tlsh_hash
                'Nullable(String)', 'Nullable(String)',
                # authentihash, imphash, impfuzzy, typerefhash
                'Nullable(String)', 'Nullable(String)',
                'Nullable(String)', 'Nullable(String)',
                # richhash, richpe_hash, richpv_hash, richpv_hash_sorted
                'Nullable(String)', 'Nullable(String)',
                'Nullable(String)', 'Nullable(String)',
                # import_hash, export_hash, section_hash, symbol_hash, dynamic_hash
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))',
                # macho_dylib_hash, macho_import_hash, macho_export_hash, macho_entitlement_hash, macho_symhash
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))',
                # permhash (APK)
                'Nullable(FixedString(64))',
                # analysis_date
                'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)

    def get_clickhouse_table(self) -> str:
        return "redb_hashes"

    def tag(self):
        return Tag.HASH.value