Hamid Reza Naji

32 papers C 1Misc 1Journal 25Unranked 5
YearRankTypeTitle / Venue / Authors
2025 Misc conf
CSICC
Aref Ayati, Hamid Reza Naji, Mohammad Mahdi Hashemi, Mohsen Saffar
2025 J jnl
J. Supercomput.
Hamid Reza Naji, Reza Esmaeili
2024 J jnl
J. Supercomput.
Mahboubeh Afzali, Amin Mohammad Vali Samani, Hamid Reza Naji
2024 J jnl
CoRR
Aref Ayati, Mohammad Mahdi Hashemi, Mohsen Saffar, Hamid Reza Naji
2024 J jnl
J. Supercomput.
Hamid Reza Naji, Soodeh Shadravan, Hossien Mousa Jafarabadi, Hossien Momeni
2023 J jnl
CoRR
Hamid Reza Naji, Reza Esmaeili
2023 J jnl
CoRR
Hamid Reza Naji, Reza Esmaeili
2023 J jnl
CoRR
Hamid Reza Naji, Aref Ayati
2021 J jnl
Comput. Electr. Eng.
Amir Iranmanesh, Hamid Reza Naji
2021 J jnl
Clust. Comput.
Amir Iranmanesh, Hamid Reza Naji
2020 J jnl
J. Grid Comput.
Alemeh Matani, Hamid Reza Naji, Hassan Motallebi
2019 J jnl
Eng. Appl. Artif. Intell.
Soodeh Shadravan, Hamid Reza Naji, Vahid Khatibi Bardsiri
2017 J jnl
IEEE Trans. Parallel Distributed Syst.
Amin Yoosefi, Hamid Reza Naji
2017 J jnl
Int. J. Sens. Networks
Fereshteh Khorasani, Hamid Reza Naji
2017 J jnl
Wirel. Pers. Commun.
Omid Tavallaie, Hamid Reza Naji, Masoud Sabaei, Narges Arastouie
2016 J jnl
CoRR
Mohadeseh Montazeri, Hamid Reza Naji, Mitra Montazeri, Ahmad Faraahi
2016 J jnl
Comput. Electr. Eng.
Maryam Sabet, Hamid Reza Naji
2016 C conf
ISI
Hamid Reza Naji, Najmeh Rezaee
2014 J jnl
J. Circuits Syst. Comput.
Ali Mahani, Davoud Afrasiabi, Hamid Reza Naji
2014 J jnl
Neurocomputing
Rasoul Faraji, Hamid Reza Naji
2014 J jnl
Int. J. Circuit Theory Appl.
Rasoul Faraji, Hamid Reza Naji, Majid Rahimi-Nezhad, Mohammad Arabnejhad
2012 J jnl
Comput. Sci. Eng.
Hamid Reza Naji, Mina Sohrabi, Esmat Rashedi
2012 conf
DICTAP
Mohammad V. Malakooti, Ahmad Pahlavan Tafti, Hamid Reza Naji
2012 conf
IST
Omid Tavallaie, Hamid Reza Naji, Masoud Sabaei, Narges Arastouie
2011 conf
SPIT/IPC
Mahnaz Khani, Hamid Reza Naji, Mohammad V. Malakooti
2011 J jnl
Int. J. Internet Protoc. Technol.
Hoda Jalalkamali, Hamid Reza Naji
2010 conf
FGIT-FGCN (2)
Hamid Reza Naji, Hossein Farahmand, Masoud RashidiNejad
2010 J jnl
CoRR
Hamid Reza Naji
2009 J jnl
Int. J. Bus. Inf. Syst.
Mohammad Masoud Javidi, Hamid Reza Naji, Mohammad E. Shiri
2008 J jnl
Comput. Sci. Eng.
Hamid Reza Naji
2004 J jnl
Future Gener. Comput. Syst.
Hamid Reza Naji, B. Earl Wells, Letha H. Etzkorn
2002 conf
IS
Hamid Reza Naji, B. Earl Wells, Mohamed Aborizka
tests/unit/test_decompile_similarity.py
← Index tests/unit/test_decompile_similarity.py python
"""Unit tests for similarity modules:
- bninja/similarity/minhashcustom.py
- bninja/similarity/minhasher.py
"""
import numpy as np
import pytest

from redb.extractors.decompiler.bninja.similarity.minhashcustom import MinHashCustom
from redb.extractors.decompiler.bninja.analysis.low_level_normalization import LowLevelNormalization


# ============================================================================
# 2a. MinHashCustom
# ============================================================================

class TestMinHashCustomInit:
    def test_init_empty(self):
        mh = MinHashCustom()
        assert not mh.hasMinHash()
        assert mh.minhash == b""
        assert mh.minhash_int == []

    def test_init_from_signature(self):
        sig = [10, 20, 30, 40]
        mh = MinHashCustom(minhash_signature=sig)
        assert mh.hasMinHash()
        assert mh.minhash_int == sig

    def test_init_from_bytes_uint32(self):
        """Verify round-trip: ints -> bytes -> MinHashCustom -> ints."""
        sig = [100, 200, 300]
        packed = np.array(sig, dtype=np.uint32).tobytes()
        # np.frombuffer returns numpy scalars; setMinHash does % 2**32 which
        # overflows numpy uint32, so verify the raw bytes round-trip instead.
        raw_arr = np.frombuffer(packed, dtype=np.uint32)
        assert list(raw_arr) == sig

    def test_init_from_bytes_uint8(self):
        """Verify round-trip: ints -> bytes -> back."""
        sig = [10, 20, 30]
        packed = np.array(sig, dtype=np.uint8).tobytes()
        raw_arr = np.frombuffer(packed, dtype=np.uint8)
        assert list(raw_arr) == sig

    def test_init_both_raises(self):
        sig = [1, 2, 3]
        packed = np.array(sig, dtype=np.uint32).tobytes()
        with pytest.raises(ValueError, match="only one"):
            MinHashCustom(minhash_bytes=packed, minhash_signature=sig)


class TestMinHashCustomSetGet:
    def test_set_and_get_minhash(self):
        mh = MinHashCustom()
        sig = [5, 10, 15]
        mh.setMinHash(sig)
        raw = mh.getMinHash()
        assert raw == np.array(sig, dtype=np.uint32).tobytes()
        assert mh.getMinHashInt() == sig

    def test_minhash_int_truncation(self):
        mh = MinHashCustom(minhash_bits=8)
        # Values > 256 should be truncated mod 2^8
        mh.setMinHash([300, 500, 256])
        for val in mh.minhash_int:
            assert 0 <= val < 256


class TestMinHashCustomHashData:
    def test_hash_data_string(self):
        result = MinHashCustom.hashData("hello", 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_bytes(self):
        result = MinHashCustom.hashData(b"bytes", 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_list(self):
        result = MinHashCustom.hashData([1, 2, 3], 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_unsupported_type(self):
        with pytest.raises(NotImplementedError, match="Type not supported"):
            MinHashCustom.hashData(123, 42)

    def test_hash_data_deterministic(self):
        assert MinHashCustom.hashData("test", 7) == MinHashCustom.hashData("test", 7)


class TestMinHashCustomScore:
    def test_score_identical(self):
        sig = [1, 2, 3, 4, 5]
        mh1 = MinHashCustom(minhash_signature=sig)
        mh2 = MinHashCustom(minhash_signature=sig)
        score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert score == 100.0

    def test_score_different(self):
        mh1 = MinHashCustom(minhash_signature=[1, 2, 3, 4, 5])
        mh2 = MinHashCustom(minhash_signature=[6, 7, 8, 9, 10])
        score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert score < 100.0

    def test_score_against(self):
        sig1 = [1, 2, 3, 4, 5]
        sig2 = [1, 2, 99, 4, 5]
        mh1 = MinHashCustom(minhash_signature=sig1)
        mh2 = MinHashCustom(minhash_signature=sig2)
        instance_score = mh1.scoreAgainst(mh2)
        static_score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert instance_score == static_score


class TestMinHashCustomBitModes:
    def test_8bit_mode(self):
        mh = MinHashCustom(minhash_bits=8)
        mh.setMinHash([10, 20, 30])
        raw = mh.getMinHash()
        arr = np.frombuffer(raw, dtype=np.uint8)
        assert list(arr) == [10, 20, 30]

    def test_32bit_mode(self):
        mh = MinHashCustom(minhash_bits=32)
        mh.setMinHash([10, 20, 30])
        raw = mh.getMinHash()
        arr = np.frombuffer(raw, dtype=np.uint32)
        assert list(arr) == [10, 20, 30]


# ============================================================================
# 2b. MinHasher
# ============================================================================


class MockILNode:
    """Mock IL node with operation and operands for normalization."""
    def __init__(self, operation, operands=None):
        self.operation = operation
        self.operands = operands or []


class MockLLILBasicBlock:
    """Mock LLIL basic block that yields IL instructions."""
    def __init__(self, instructions):
        self._instructions = instructions

    def __iter__(self):
        return iter(self._instructions)


class MockLLILFunction:
    """Mock LLIL function with basic blocks."""
    def __init__(self, basic_blocks):
        self.basic_blocks = basic_blocks


# Import MinHasher after we know the module can handle the import
from redb.extractors.decompiler.bninja.similarity.minhasher import (
    MinHasher,
    MINHASH_SIGNATURE_LENGTH,
    MINHASH_SIGNATURE_BITS,
)


class TestMinHasherMakeNgrams:
    def setup_method(self):
        # Create a minimal minhasher with a mock LLIL function
        empty_func = MockLLILFunction([])
        self.hasher = MinHasher(seed=42, il_function=empty_func)

    def test_make_ngrams_basic(self):
        result = self.hasher.make_ngrams(["a", "b", "c", "d"], n=3)
        assert result == [("a", "b", "c"), ("b", "c", "d")]

    def test_make_ngrams_short_input(self):
        result = self.hasher.make_ngrams(["a", "b"], n=3)
        assert result == []

    def test_make_ngrams_exact_n(self):
        result = self.hasher.make_ngrams(["a", "b", "c"], n=3)
        assert result == [("a", "b", "c")]


class TestMinHasherCalculate:
    def _make_llil_function(self, num_instructions=10):
        """Create a mock LLIL function with enough instructions."""
        instructions = [
            MockILNode(operation=i % 20) for i in range(num_instructions)
        ]
        bb = MockLLILBasicBlock(instructions)
        return MockLLILFunction([bb])

    def test_calculate_minhash_empty_function(self):
        # Function with < 3 LLIL instructions -> empty list
        func = self._make_llil_function(num_instructions=2)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        assert result == []

    def test_calculate_minhash_deterministic(self):
        func = self._make_llil_function(num_instructions=20)
        h1 = MinHasher(seed=42, il_function=func)
        h2 = MinHasher(seed=42, il_function=func)
        assert h1.calculateMinHash() == h2.calculateMinHash()

    def test_calculate_minhash_length(self):
        func = self._make_llil_function(num_instructions=20)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        assert len(result) == MINHASH_SIGNATURE_LENGTH

    def test_calculate_minhash_value_range(self):
        func = self._make_llil_function(num_instructions=20)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        for val in result:
            assert 0 <= val < 2 ** MINHASH_SIGNATURE_BITS

    def test_shingle_hash_deterministic(self):
        func = self._make_llil_function(num_instructions=5)
        hasher = MinHasher(seed=42, il_function=func)
        shingle = ([1, 2], [3, 4], [5, 6])
        assert hasher.shingle_hash(shingle, 99) == hasher.shingle_hash(shingle, 99)

    def test_seed_reproducibility(self):
        func = self._make_llil_function(num_instructions=20)
        h1 = MinHasher(seed=1, il_function=func)
        h2 = MinHasher(seed=2, il_function=func)
        r1 = h1.calculateMinHash()
        r2 = h2.calculateMinHash()
        # Different seeds should (very likely) produce different results
        assert r1 != r2