Rachid Oulad Haj Thami

56 papers A 1B 1C 3Misc 3Journal 24Unranked 24
YearRankTypeTitle / Venue / Authors
2025 J jnl
Appl. Intell.
Oumaima Guendoul, Maryem Zobi, Hamd Ait Abdelali, Youness Tabii, Rachid Oulad Haj Thami, Omar Bourja
2025 J jnl
Inf.
Merieme Elkorchi, Boutaina Hdioud, Rachid Oulad Haj Thami, Safae Merzouk
2025 conf
CiST
Fatiha Limami, Boutaina Hdioud, Rachid Oulad Haj Thami
2025 J jnl
IEEE Access
Asma Amalas, Mounir Ghogho, Yousra Fettach, Ouassim Karrakchou, Rachid Oulad Haj Thami
2024 J jnl
CoRR
Asma Amalas, Mounir Ghogho, Mohamed Chetouani, Rachid Oulad Haj Thami
2024 J jnl
Frontiers Artif. Intell.
Fatiha Limami, Boutaina Hdioud, Rachid Oulad Haj Thami
2024 J jnl
Frontiers Artif. Intell.
Fatiha Limami, Boutaina Hdioud, Rachid Oulad Haj Thami
2024 J jnl
IEEE Access
Oumaima Guendoul, Hamd Ait Abdelali, Youness Tabii, Rachid Oulad Haj Thami, Omar Bourja
2024 J jnl
Soc. Netw. Anal. Min.
Naaima Boudad, Rdouan Faizi, Rachid Oulad Haj Thami
2022 J jnl
J. Imaging
Mohamed Alimoussa, Alice Porebski, Nicolas Vandenbroucke, Sanaa El Fkihi, Rachid Oulad Haj Thami
2022 J jnl
Neural Comput. Appl.
Hatim Derrouz, Alberto Cabri, Hamd Ait Abdelali, Rachid Oulad Haj Thami, François Bourzeix, Stefano Rovetta, Francesco Masulli
2022 J jnl
Int. J. Online Biomed. Eng.
Abdelhafid Errabih, Mohyeddine Boussarhane, Benayad Nsiri, Abdelalim Sadiq, My Hachem El Yousfi Alaoui, Rachid Oulad Haj Thami, Brahim Benaji
2022 J jnl
Comput. Stat.
Said Benlakhdar, Mohammed Rziza, Rachid Oulad Haj Thami
2021 conf
VISIGRAPP (4: VISAPP)
Mohamed Alimoussa, Alice Porebski, Nicolas Vandenbroucke, Rachid Oulad Haj Thami, Sanaa El Fkihi
2021 J jnl
J. Imaging
Abderrazak Iazzi, Mohammed Rziza, Rachid Oulad Haj Thami
2021 J jnl
J. Imaging
Abdessamad Youssfi Alaoui, Youness Tabii, Rachid Oulad Haj Thami, Mohamed Daoudi, Stefano Berretti, Pietro Pala
2021 J jnl
IEEE Access
Hamd Ait Abdelali, Hatim Derrouz, Yahya Zennayi, Rachid Oulad Haj Thami, François Bourzeix
2020 J jnl
Comput. Vis. Media
Abderrazak Iazzi, Mohammed Rziza, Rachid Oulad Haj Thami
2019 conf
VISIGRAPP (4: VISAPP)
Mohamed Alimoussa, Nicolas Vandenbroucke, Alice Porebski, Rachid Oulad Haj Thami, Sanaa El Fkihi, Denis Hamad
2019 J jnl
IEEE Access
Abdessamad Youssfi Alaoui, Sanaa El Fkihi, Rachid Oulad Haj Thami
2019 J jnl
IEEE Access
Hatim Derrouz, Abderrahim El Bouziady, Hamd Ait Abdelali, Rachid Oulad Haj Thami, Sanaa El Fkihi, François Bourzeix
2019 conf
NISS
Marouane Adnane, Mohammed El Haj Tirari, Sanaa El Fkihi, Rachid Oulad Haj Thami
2018 conf
ISIVC
Abdelghaffar Chibloun, Sanaa El Fkihi, Hazar Mliki, Mohamed Hammami, Rachid Oulad Haj Thami
2018 J jnl
EAI Endorsed Trans. Ubiquitous Environ.
H. Kamdem Fezeu, Thomas Ndié Djotio, Rachid Oulad Haj Thami
2018 conf
CIST
Basma Essatouti, Hakima Khamar, Sanaa El Fkihi, Rdouan Faizi, Rachid Oulad Haj Thami
2018 Misc conf
ATSIP
Abderrazak Iazzi, Mohammed Rziza, Rachid Oulad Haj Thami
2018 conf
ISIVC
Abderrazak Iazzi, Mohammed Rziza, Rachid Oulad Haj Thami
2018 conf
CIST
Omar Bourja, Kaoutar Kabbaj, Hatim Derrouz, Abderrahim El Bouziady, Rachid Oulad Haj Thami, Yahya Zennayi, François Bourzeix
2018 conf
ISIVC
Wafae Mrabti, Kaoutar Baibai, Benaissa Bellach, Rachid Oulad Haj Thami, Hamid Tairi
2018 conf
LOPAL
Boutaina Hdioud, Mohammed El Haj Tirari, Rachid Oulad Haj Thami
2017 Misc conf
ATSIP
Adil Er-Rady, Rdouan Faizi, Rachid Oulad Haj Thami, H. Housni
2017 conf
BDCA
Said Benlakhdar, Mohammed Rziza, Rachid Oulad Haj Thami
2017 conf
BDCA
Abdessamad Youssfi Alaoui, Azeddine Elhassouny, Rachid Oulad Haj Thami, Hamid Tairi
2017 conf
BDCA
H. Kamdem Fezeu, Thomas Ndié Djotio, Rachid Oulad Haj Thami
2017 J jnl
CoRR
Géraldin Nanfack, Azeddine Elhassouny, Rachid Oulad Haj Thami
2017 C conf
ICMV
Géraldin Nanfack, Azeddine Elhassouny, Rachid Oulad Haj Thami
2016 conf
ISVC (2)
Abderrazak Iazzi, Mohammed Rziza, Rachid Oulad Haj Thami, Driss Aboutajdine
2016 conf
ICMCS
Anas Abouyahya, Sanaa El Fkihi, Rachid Oulad Haj Thami, Driss Aboutajdine
2015 C conf
AICCSA
Abderrazak Iazzi, Rachid Oulad Haj Thami, Mohammed Rziza
2014 conf
SITA
Mohammed Romadi, Rachid Oulad Haj Thami, Rahal Romadi, Raddouane Chiheb
2009 conf
IPCV
Youness Tabii, Rachid Oulad Haj Thami
2008 conf
EGC
Youssef Hadi, Rachid El Meziane, Rachid Oulad Haj Thami
2008 J jnl
ACM Journal on Computing and Cultural Heritage
Mohamed Ould Djibril, Rachid Oulad Haj Thami
2007 conf
VISAPP (1)
Youness Tabii, Mohamed Ould Djibril, Youssef Hadi, Rachid Oulad Haj Thami
2007 J jnl
J. Real Time Image Process.
Fedwa Essannouni, Rachid Oulad Haj Thami, Driss Aboutajdine, Ahmed Salam
2007 conf
ICECS
Fedwa Essannouni, Rachid Oulad Haj Thami, Driss Aboutajdine, Ahmed Salam
2006 A conf
ICME
Fedwa Essannouni, Rachid Oulad Haj Thami, Ahmed Salam, Driss Aboutajdine
2006 conf
ICIAR (2)
Mohamed Ould Djibril, Youssef Hadi, Rachid Oulad Haj Thami
2006 conf
MRCS
Ibrahima Mbaye, José Martinez, Rachid Oulad Haj Thami
2006 Misc conf
SAC
Youssef Hadi, Fedwa Essannouni, Rachid Oulad Haj Thami
2005 C conf
MMSP
Ibrahima Mbaye, Rachid Oulad Haj Thami, José Martinez
2005 conf
ISSPA
Fedwa Essannouni, Rachid Oulad Haj Thami, Ahmed Salam, Driss Aboutajdine
2005 B conf
SMC
Fedwa Essannouni, Rachid Oulad Haj Thami, Ahmed Salam, Driss Aboutajdine
2003 J jnl
Ingénierie des Systèmes d Inf.
Ibrahima Mbaye, José Martinez, Rachid Oulad Haj Thami
2003 J jnl
Ann. des Télécommunications
Rachid Oulad Haj Thami, Hind Chaarani, Mohamed Daoudi, Mustapha Rachik
2001 conf
BDA
Rachid Oulad Haj Thami, Mohamed Daoudi, Youssef El Mansouri
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