Carlos F. Uribe

21 papers B 5Journal 13Unranked 3
YearRankTypeTitle / Venue / Authors
2025 J jnl
CoRR
Alejandro López-Montes, Fereshteh Yousefirizi, Yizhou Chen, Yazdan Salimi, Robert Seifert, Ali Afshar-Oromieh, Carlos F. Uribe, Axel Rominger, Habib Zaidi, Arman Rahmim, Kuangyu Shi
2025 J jnl
SoftwareX
Lucas A. Polson, Roberto Fedrigo, Chenguang Li, Maziar Sabouri, Obed Dzikunu, Shadab Ahamed, Nicolas A. Karakatsanis, Sara Kurkowska, Peyman Sheikhzadeh, Pedro L. Esquinas, Arman Rahmim, Carlos F. Uribe
2025 J jnl
J. Open Source Softw.
Asim Shrestha, Adam Watkins, Fereshteh Yousefirizi, Arman Rahmim, Carlos F. Uribe
2025 J jnl
IEEE Trans. Medical Imaging
Lucas A. Polson, Sara Kurkowska, Chenguang Li, Pedro L. Esquinas, Peyman Sheikhzadeh, Mehrshad Abbasi, François Bénard, Carlos F. Uribe, Arman Rahmim
2024 J jnl
CoRR
Shadab Ahamed, Natalia Dubljevic, Ingrid Bloise, Claire Gowdy, Patrick Martineau, Don Wilson, Carlos F. Uribe, Arman Rahmim, Fereshteh Yousefirizi
2024 J jnl
CoRR
Shadab Ahamed, Yixi Xu, Ingrid Bloise, Joo H. O, Carlos F. Uribe, Rahul Dodhia, Juan M. Lavista Ferres, Arman Rahmim
2024 J jnl
CoRR
Amirhosein Toosi, Sara Harsini, François Bénard, Carlos F. Uribe, Arman Rahmim
2024 conf
DGM4MICCAI@MICCAI
Amirhosein Toosi, Sara Harsini, François Bénard, Carlos F. Uribe, Arman Rahmim
2024 J jnl
J. Open Source Softw.
Obed Dzikunu, Maziar Sabouri, Shadab Ahamed, Carlos F. Uribe, Arman Rahmim, Lucas A. Polson
2024 J jnl
Comput. Methods Programs Biomed.
Anahita Piranfar, Madjid Soltani, Farshad Moradi Kashkooli, Carlos F. Uribe, Arman Rahmim
2024 conf
EUVIP
Maziar Sabouri, Shadab Ahamed, Azin Asadzadeh, Atlas Haddadi Avval, Soroush Bagheri, Mohsen Arabi, Seyed Rasoul Zakavi, Emran Askari, Ali Rasouli, Atena Aghaee, Mohaddese Sehati, Fereshteh Yousefirizi, Carlos F. Uribe, Ghasem Hajianfar, Habib Zaidi, Arman Rahmim
2024 J jnl
CoRR
Maziar Sabouri, Shadab Ahamed, Azin Asadzadeh, Atlas Haddadi Avval, Soroush Bagheri, Mohsen Arabi, Seyed Rasoul Zakavi, Emran Askari, Ali Rasouli, Atena Aghaee, Mohaddese Sehati, Fereshteh Yousefirizi, Carlos F. Uribe, Ghasem Hajianfar, Habib Zaidi, Arman Rahmim
2023 B conf
Image Processing
Shadab Ahamed, Yixi Xu, Ingrid Bloise, Joo Hyun O, Carlos F. Uribe, Rahul Dodhia, Juan M. Lavista Ferres, Arman Rahmim
2023 J jnl
Comput. Biol. Medicine
Yixi Xu, Ivan S. Klyuzhin, Sara Harsini, Anthony Ortiz, Shun Zhang, François Bénard, Rahul Dodhia, Carlos F. Uribe, Arman Rahmim, Juan M. Lavista Ferres
2023 J jnl
CoRR
Shadab Ahamed, Yixi Xu, Claire Gowdy, Joo Hyun O, Ingrid Bloise, Don Wilson, Patrick Martineau, François Bénard, Fereshteh Yousefirizi, Rahul Dodhia, Juan M. Lavista Ferres, William B. Weeks, Carlos F. Uribe, Arman Rahmim
2023 conf
Image Perception, Observer Performance, and Technology Assessment
Roberto Fedrigo, Fereshteh Yousefirizi, Ziping Liu, Abhinav K. Jha, Robert V. Bergen, Jean-François Rajotte, Raymond T. Ng, Ingrid Bloise, Sara Harsini, Dan J. Kadrmas, Carlos F. Uribe, Arman Rahmim
2023 B conf
Image Processing
Fereshteh Yousefirizi, Joo Hyun O, Ingrid Bloise, Amirhosein Toosi, Carlos F. Uribe, Arman Rahmim
2023 B conf
Image Processing
Amirhosein Toosi, Sara Harsini, Shadab Ahamed, Fereshteh Yousefirizi, François Bénard, Carlos F. Uribe, Arman Rahmim
2022 B conf
Image Processing
Shadab Ahamed, Natalia Dubljevic, Ingrid Bloise, Claire Gowdy, Patrick Martineau, Don Wilson, Carlos F. Uribe, Arman Rahmim, Fereshteh Yousefirizi
2022 B conf
Image Processing
Fereshteh Yousefirizi, Natalia Dubljevic, Shadab Ahamed, Ingrid Bloise, Claire Gowdy, Joo Hyun O, Youssef Farag, Rodrigue de Schaetzen, Patrick Martineau, Don Wilson, Carlos F. Uribe, Arman Rahmim
2022 J jnl
CoRR
Arman Rahmim, Amirhosein Toosi, Mohammad R. Salmanpour, Natalia Dubljevic, Ian Janzen, Isaac Shiri, Mohamad A. Ramezani, Ren Yuan, Cheryl Ho, Habib Zaidi, Calum MacAulay, Carlos F. Uribe, Fereshteh Yousefirizi
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