Can Chen

98 papers A* 6B 1C 3Journal 73Unranked 15
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Netw. Sci. Eng.
Can Chen, Qinghao Wang, Ning Lu, Wenbo Shi, Zhiquan Liu
2026 J jnl
CoRR
Dev Mistry, Feng Qiu, Bo Chen, Feng Liu, Can Chen, Mohammad Shahidehpour, Ren Wang
2026 J jnl
IEEE Trans. Inf. Forensics Secur.
Can Chen, Qinghao Wang, Ning Lu, Wenbo Shi
2026 J jnl
CoRR
Joshua Pickard, Xin Mao, Can Chen
2025 J jnl
IEEE Trans. Emerg. Top. Comput. Intell.
Wenjing Li, Can Chen, Junfei Qiao
2025 A* conf
ICML
Can Chen, Karla-Luise Herpoldt, Chenchao Zhao, Zichen Wang, Marcus D. Collins, Shang Shang, Ron Benson
2025 J jnl
CoRR
Can Chen, Karla-Luise Herpoldt, Chenchao Zhao, Zichen Wang, Marcus D. Collins, Shang Shang, Ron Benson
2025 J jnl
Phys. Commun.
Can Chen, Lei Li, Long Zhang, Danping Ren, Xiaoyu Wu
2025 conf
HCI (4)
Can Chen, Qingchuan Li
2025 A* conf
AAAI
Yixuan Li, Can Chen, Jiajun Li, Jiahui Duan, Xiongwei Han, Tao Zhong, Vincent Chau, Weiwei Wu, Wanyuan Wang
2025 J jnl
CoRR
Yixuan Li, Can Chen, Jiajun Li, Jiahui Duan, Xiongwei Han, Tao Zhong, Vincent Chau, Weiwei Wu, Wanyuan Wang
2025 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Lei Ding, Can Chen, Maojiao Ye, Qing-Long Han
2025 J jnl
IEEE Trans. Parallel Distributed Syst.
Zijie Liu, Yi Cheng, Can Chen, Jun Hu, Rongguo Fu, Dengyin Zhang
2025 J jnl
CoRR
Yingqi Liu, Tianlu Pan, Jingjun Tan, Renxin Zhong, Can Chen
2025 J jnl
Trans. Mach. Learn. Res.
Can Chen, Gabriel L. Oliveira, Hossein Sharifi-Noghabi, Tristan Sylvain
2025 J jnl
CoRR
Can Chen, Yunping Huang, Hongwei Zhang, Shimin Wang, Martin Guay, Shu-Chien Hsu, Renxin Zhong
2025 J jnl
CoRR
Shiyi Yang, Can Chen, Didong Li
2025 J jnl
IEEE Trans. Knowl. Data Eng.
Yuan Fang, Geping Yang, Ruichu Cai, Yiyang Yang, Zhiguo Gong, Can Chen, Zhifeng Hao
2025 J jnl
CoRR
Xin Mao, Can Chen
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Jie Mei, Songhua Yan, Can Chen
2025 A* conf
ICML
Can Chen, Jun-Kun Wang
2025 conf
OFC
Junda Chen, Shengming Shi, Can Chen, Jiajun Zhou, Mingming Zhang, Zhonghong Lin, Can Zhao, Ming Tang
2025 J jnl
CoRR
Can Chen, Jun-Kun Wang
2025 J jnl
CoRR
Hanting Chen, Jiarui Qin, Jialong Guo, Tao Yuan, Yichun Yin, Huiling Zhen, Yasheng Wang, Jinpeng Li, Xiaojun Meng, Meng Zhang, Rongju Ruan, Zheyuan Bai, Yehui Tang, Can Chen, Xinghao Chen, Fisher Yu, Ruiming Tang, Yunhe Wang
2025 J jnl
CoRR
Yehui Tang, Xiaosong Li, Fangcheng Liu, Wei Guo, Hang Zhou, Yaoyuan Wang, Kai Han, Xianzhi Yu, Jinpeng Li, Hui Zang, Fei Mi, Xiaojun Meng, Zhicheng Liu, Hanting Chen, Binfan Zheng, Can Chen, Youliang Yan, Ruiming Tang, Peifeng Qin, Xinghao Chen, Dacheng Tao, Yunhe Wang
2025 J jnl
CoRR
Yehui Tang, Yichun Yin, Yaoyuan Wang, Hang Zhou, Yu Pan, Wei Guo, Zhiguo Zhang, Miao Rang, Fangcheng Liu, Naifu Zhang, Binghan Li, Yonghan Dong, Xiaojun Meng, Yasheng Wang, Dong Li, Yin Li, Dandan Tu, Can Chen, Youliang Yan, Fisher Yu, Ruiming Tang, Yunhe Wang, Botian Huang, Bo Wang, Boxiao Liu, Changzheng Zhang, Da Kuang, Fei Liu, Gang Huang, Jiansheng Wei, Jiarui Qin, Jie Ran, Jinpeng Li, Jun Zhao, Liang Dai, Lin Li, Liqun Deng, Peifeng Qin, Pengyuan Zeng, Qiang Gu, Shaohua Tang, Shengjun Cheng, Tao Gao, Tao Yu, Tianshu Li, Tianyu Bi, Wei He, Weikai Mao, Wenyong Huang, Wulong Liu, Xiabing Li, Xianzhi Yu, Xueyu Wu, Xu He, Yangkai Du, Yan Xu, Ye Tian, Yimeng Wu, Yongbing Huang, Yong Tian, Yong Zhu, Yue Li, Yufei Wang, Yuhang Gai, Yujun Li, Yu Luo, Yunsheng Ni, Yusen Sun, Zelin Chen, Zhe Liu, Zhicheng Liu, Zhipeng Tu, Zilin Ding, Zongyuan Zhan
2025 J jnl
CoRR
Yichun Yin, Wenyong Huang, Kaikai Song, Yehui Tang, Xueyu Wu, Wei Guo, Peng Guo, Yaoyuan Wang, Xiaojun Meng, Yasheng Wang, Dong Li, Can Chen, Dandan Tu, Yin Li, Fisher Yu, Ruiming Tang, Yunhe Wang, Baojun Wang, Bin Wang, Bo Wang, Boxiao Liu, Changzheng Zhang, Duyu Tang, Fei Mi, Hui Jin, Jiansheng Wei, Jiarui Qin, Jinpeng Li, Jun Zhao, Liqun Deng, Lin Li, Minghui Xu, Naifu Zhang, Nianzu Zheng, Qiang Li, Rongju Ruan, Shengjun Cheng, Tianyu Guo, Wei He, Wei Li, Weiwen Liu, Wulong Liu, Xinyi Dai, Yonghan Dong, Yu Pan, Yue Li, Yufei Wang, Yujun Li, Yunsheng Ni, Zhe Liu, Zhenhe Zhang, Zhicheng Liu
2025 J jnl
CoRR
Ziqin He, Can Chen, Min Hyung Cho, Jingfang Huang, Yichao Wu
2025 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Geping Yang, Shusen Yang, Yiyang Yang, Xiang Chen, Can Chen, Zhiguo Gong, Zhifeng Hao
2024 J jnl
IEEE Geosci. Remote. Sens. Lett.
Can Chen, Songhua Yan, Jie Mei
2024 J jnl
CoRR
Jiajie Song, Ningfang Song, Xiong Pan, Xiaoxin Liu, Can Chen, Jingchun Cheng
2024 J jnl
Adv. Eng. Informatics
Wenxue Han, Weiming Shao, Chihang Wei, Wei Song, Can Chen, Junghui Chen
2024 J jnl
Transp. Sci.
Can Chen, Nikolas Geroliminis, Renxin Zhong
2024 J jnl
INFORMS J. Appl. Anal.
Jiayun Wang, Shanshan Wu, Qingwei Jin, Yijun Wang, Can Chen
2024 J jnl
CoRR
Can Chen, Gabriel L. Oliveira, Hossein Sharifi Noghabi, Tristan Sylvain
2024 J jnl
Inf. Sci.
Yuan Fang, Geping Yang, Xiang Chen, Zhiguo Gong, Yiyang Yang, Can Chen, Zhifeng Hao
2024 J jnl
Pattern Recognit.
Sucheng Deng, Geping Yang, Yiyang Yang, Zhiguo Gong, Can Chen, Xiang Chen, Zhifeng Hao
2024 J jnl
CoRR
Can Chen, Jun-Kun Wang
2024 J jnl
CoRR
Canqiang Weng, Can Chen, Jingjun Tan, Tianlu Pan, Renxin Zhong
2024 conf
ITSC
Can Chen, Yunping Huang, Hongwei Zhang, Shu-Chien Hsu, Renxin Zhong
2023 conf
OFC
Can Chen, Zhiyong Zhao, Zhonghong Lin, Yucheng Yao, Weijun Tong, Ming Tang
2023 J jnl
IEEE Trans. Intell. Transp. Syst.
Simin Jiang, Tianlu Pan, Renxin Zhong, Can Chen, Xin-an Li, Shimin Wang
2023 J jnl
Comput. Biol. Medicine
Kangshun Li, Can Chen, Wuteng Cao, Hui Wang, Shuai Han, Renjie Wang, Zaisheng Ye, Zhijie Wu, Wenxiang Wang, Leng Cai, Deyu Ding, Zixu Yuan
2023 J jnl
Neural Comput. Appl.
Simin Li, Yulan Lin, Tong Zhu, Mengjie Fan, Shicheng Xu, Weihao Qiu, Can Chen, Linfeng Li, Yao Wang, Jun Yan, Justin Wong, Lin Naing, Shabei Xu
2023 J jnl
IEEE Trans. Knowl. Data Eng.
Geping Yang, Sucheng Deng, Can Chen, Yiyang Yang, Zhiguo Gong, Xiang Chen, Zhifeng Hao
2023 J jnl
BMC Medical Imaging
Can Chen, Meng Chen, Qing Tao, Su Hu, Chunhong Hu
2023 J jnl
IET Signal Process.
Ding Wang, Jiexin Yin, Can Chen, Jianyang Li
2023 J jnl
Pattern Recognit.
Geping Yang, Sucheng Deng, Xiang Chen, Can Chen, Yiyang Yang, Zhiguo Gong, Zhifeng Hao
2023 J jnl
CoRR
Can Chen, Xu-Wen Wang, Yang-Yu Liu
2023 J jnl
IEICE Trans. Inf. Syst.
Zijie Liu, Can Chen, Yi Cheng, Maomao Ji, Jinrong Zou, Dengyin Zhang
2022 J jnl
CoRR
Can Chen, Yang-Yu Liu
2022 J jnl
Intell. Autom. Soft Comput.
Aitizaz Ali, Mehedi Masud, Ateeq Ur Rehman, Can Chen, Mehmood, Mohammed Abdullatif Alzain, Jehad Ali
2022 J jnl
IEEE Access
Jinhang Huang, Haixia Cui, Can Chen
2022 J jnl
CoRR
Can Chen, Scott T. Weiss, Yang-Yu Liu
2022 J jnl
INFORMS J. Comput.
Junming Liu, Weiwei Chen, Jingyuan Yang, Hui Xiong, Can Chen
2022 J jnl
Concurr. Comput. Pract. Exp.
Zijie Liu, Can Chen, Junjiang Li, Yi Cheng, Yingjie Kou, Dengyin Zhang
2021 J jnl
Comput. Aided Civ. Infrastructure Eng.
Keshuang Tang, Yumin Cao, Can Chen, Jiarong Yao, Chaopeng Tan, Jian Sun
2021 J jnl
CoRR
Can Chen
2021 J jnl
Neurocomputing
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2021 J jnl
CoRR
Can Chen
2021 J jnl
Sensors
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2021 J jnl
IEEE Geosci. Remote. Sens. Lett.
Zhicheng Zhao, Jiaqi Li, Ze Luo, Jian Li, Can Chen
2021 J jnl
IEEE Access
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2021 conf
ComComAP
Can Chen, Jinghang Huang, Haixia Cui
2021 conf
ISICA
Can Chen, Kangshun Li
2021 conf
WCSP
Weidan Yan, Can Chen, Dengyin Zhang
2020 J jnl
J. Comput. Biol.
Tian Zeng, Can Chen, Pan Yang, Wenwei Zuo, Xiaoqing Liu, Yanling Zhang
2020 conf
eLEOT (2)
Yun-fei Qin, Lu-zhen Mo, Can Chen
2020 J jnl
CoRR
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2020 J jnl
CoRR
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2020 conf
ICCPR
Le Wang, Ze Luo, Jian Li, Can Chen
2020 J jnl
Remote. Sens.
Ning Lu, Can Chen, Wenbo Shi, Junwei Zhang, Jianfeng Ma
2020 J jnl
Remote. Sens.
Zhicheng Zhao, Ze Luo, Jian Li, Can Chen, Yingchao Piao
2019 C conf
VEHITS
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2019 J jnl
J. Medical Syst.
Can Chen, Manyun Yan, Yang Yu, Jun Ke, Chunyang Xu, Xiaoning Guo, Haifeng Lu, Ximing Wang, Lan Hu, Jingwen Wang, Jianqiang Ni, Hongru Zhao
2019 J jnl
CoRR
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2019 J jnl
CoRR
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2019 J jnl
CoRR
Can Chen, Luca Zanotti Fragonara, Antonios Tsourdos
2019 conf
IEEE BigData
Can Chen, Yijun Wang, Guoan Huang, Hui Xiong
2019 A* conf
ICDM
Chen Zhang, Hao Wang, Liang Zhou, Yijun Wang, Can Chen
2018 J jnl
IEEE Access
Yuntao Ju, Can Chen, Linlin Wu, Hui Liu
2018 J jnl
Int. J. Bifurc. Chaos
Can Chen, Xi Chen
2018 A* conf
KDD
Chen Zhang, Yijun Wang, Can Chen, Changying Du, Hongzhi Yin, Hao Wang
2018 conf
CITS
Meng Dong, Zhiliang Qiu, Weitao Pan, Can Chen, Junxiang Zhang, Dong Zhang
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Can Chen, Yanmei Kang
2017 J jnl
ACM Trans. Knowl. Discov. Data
Guannan Liu, Yanjie Fu, Guoqing Chen, Hui Xiong, Can Chen
2017 J jnl
Eur. J. Oper. Res.
Yugang Yu, Jie Liu, Xiaoya Han, Can Chen
2017 J jnl
IEICE Trans. Inf. Syst.
Can Chen, Dengyin Zhang, Jian Liu
2017 A* conf
ICDM
Can Chen, Junming Liu, Qiao Li, Yijun Wang, Hui Xiong, Shanshan Wu
2016 B conf
ICCP
Siu-Kei Tin, Jinwei Ye, Mahdi Nezamabadi, Can Chen
2016 J jnl
IEEE Trans. Mob. Comput.
Yanjie Fu, Hui Xiong, Xinjiang Lu, Jin Yang, Can Chen
2012 conf
IScIDE
Peng Yao, Can Chen, Dongdong Weng
2012 J jnl
J. Softw.
Pengzhong Li, Weimin Zhang, Can Chen
2010 C conf
IGARSS
Ruoming Shi, Can Chen, Ling Zhu, Xihan Mu
2010 conf
FSKD
Can Chen, Ruixue Fu
2008 conf
WKDD
Can Chen, Zhanhong Xin
2007 conf
FSKD (3)
Yaxin Yu, Guoren Wang, Can Chen, Chong Fu
2004 C conf
ACC
Shin Kanno, Can Chen
redb/extractors/decompiler/bninja/analysis/cfg_features.py
← Index redb/extractors/decompiler/bninja/analysis/cfg_features.py python
import struct
from collections import deque
from typing import Optional

import blake3
import mmh3


# ---------------------------------------------------------------------------
# Task 1.1: Core Graph Utilities
# ---------------------------------------------------------------------------

def bfs_order(successors: list[list[int]], n: int) -> list[int]:
    """
    BFS traversal from node 0 (entry block), returns node indices in visit order.
    Unreachable nodes appended at the end.
    """
    if n == 0:
        return []

    visited = set()
    order = []
    queue = deque([0])
    visited.add(0)

    while queue:
        idx = queue.popleft()
        order.append(idx)
        for target in successors[idx]:
            if target not in visited:
                visited.add(target)
                queue.append(target)

    # Append unreachable blocks (dead code)
    for i in range(n):
        if i not in visited:
            order.append(i)

    return order


def bfs_max_depth(successors: list[list[int]], n: int) -> int:
    """
    Maximum BFS depth from entry block (node 0).
    Replaces the per-block depth column with a single scalar.
    """
    if n == 0:
        return 0

    depth = {0: 0}
    max_d = 0
    queue = deque([0])

    while queue:
        node = queue.popleft()
        for s in successors[node]:
            if s not in depth:
                depth[s] = depth[node] + 1
                if depth[s] > max_d:
                    max_d = depth[s]
                queue.append(s)

    return max_d


# ---------------------------------------------------------------------------
# Task 1.2: Back-Edge Detection (Iterative DFS)
# ---------------------------------------------------------------------------

def count_back_edges(successors: list[list[int]], n: int) -> int:
    """
    Count natural loops via iterative DFS back-edge detection.
    A back edge is an edge to a GRAY (in-stack) node.

    Iterative to avoid stack overflow on functions with 1000+ blocks
    (common in obfuscated malware, VM dispatchers, unrolled loops).
    """
    if n == 0:
        return 0

    WHITE, GRAY, BLACK = 0, 1, 2
    color = [WHITE] * n
    back_edges = 0

    stack = [(0, iter(successors[0]))]
    color[0] = GRAY

    while stack:
        u, children = stack[-1]
        try:
            v = next(children)
            if color[v] == GRAY:
                back_edges += 1
            elif color[v] == WHITE:
                color[v] = GRAY
                stack.append((v, iter(successors[v])))
        except StopIteration:
            color[u] = BLACK
            stack.pop()

    return back_edges


# ---------------------------------------------------------------------------
# Task 1.3: Topology Hash
# ---------------------------------------------------------------------------

def compute_topology_hash(
    successors: list[list[int]],
    bfs: list[int],
    n: int,
) -> bytes:
    """
    BLAKE3 hash of BFS-ordered canonical adjacency.
    Pure graph shape — ignores all block content.
    Two functions with identical control flow structure produce identical hashes.

    Returns 16 bytes (128-bit).
    """
    if n == 0:
        return b'\x00' * 16

    # Remap: original index -> BFS position
    remap = {original: position for position, original in enumerate(bfs)}

    canonical = bytearray()
    for position in range(n):
        original_idx = bfs[position]
        remapped_succs = sorted(
            remap[s] for s in successors[original_idx] if s in remap
        )
        # Pack: node_index (2 bytes) + num_successors (1 byte) + successor indices (2 bytes each)
        canonical.extend(struct.pack('<HB', position, len(remapped_succs)))
        for s in remapped_succs:
            canonical.extend(struct.pack('<H', s))

    return blake3.blake3(bytes(canonical)).digest(length=16)


# ---------------------------------------------------------------------------
# Task 1.4: MD-Index (Top-Down and Bottom-Up)
# ---------------------------------------------------------------------------

def compute_md_index_topdown(
    successors: list[list[int]],
    predecessors: list[list[int]],
    bfs: list[int],
) -> int:
    """
    BinDiff-style top-down MD-index.
    Hash of (in_degree, out_degree) sequence in BFS order from entry.
    Returns UInt64.
    """
    if not bfs:
        return 0

    degree_bytes = bytearray()
    for idx in bfs:
        in_deg = min(len(predecessors[idx]), 255)
        out_deg = min(len(successors[idx]), 255)
        degree_bytes.extend(struct.pack('<BB', in_deg, out_deg))

    h = blake3.blake3(bytes(degree_bytes)).digest(length=8)
    return struct.unpack('<Q', h)[0]


def compute_md_index_bottomup(
    successors: list[list[int]],
    predecessors: list[list[int]],
    n: int,
) -> int:
    """
    Bottom-up MD-index: BFS from exit blocks (no successors),
    traversing edges in reverse.
    Returns UInt64.
    """
    if n == 0:
        return 0

    exits = [i for i in range(n) if len(successors[i]) == 0]
    if not exits:
        exits = [n - 1]  # Fallback: use last block

    visited = set(exits)
    order = []
    queue = deque(exits)

    while queue:
        idx = queue.popleft()
        order.append(idx)
        for pred in predecessors[idx]:
            if pred not in visited:
                visited.add(pred)
                queue.append(pred)

    # Append unreachable blocks
    for i in range(n):
        if i not in visited:
            order.append(i)

    degree_bytes = bytearray()
    for idx in order:
        in_deg = min(len(predecessors[idx]), 255)
        out_deg = min(len(successors[idx]), 255)
        degree_bytes.extend(struct.pack('<BB', in_deg, out_deg))

    h = blake3.blake3(bytes(degree_bytes)).digest(length=8)
    return struct.unpack('<Q', h)[0]


# ---------------------------------------------------------------------------
# Task 1.5: Prime Product
# ---------------------------------------------------------------------------

# Small primes assigned to LLIL opcode categories.
# Keys are the integer values of binaryninja.LowLevelILOperation enum members.
# We use integer keys so this module doesn't import binaryninja.
#
# Mapping rationale: same operation class -> same prime.
# Using LLIL (not native asm) makes this architecture-independent.
#
# Populated at import time by cfg.py using the real LowLevelILOperation enum values.
# Unknown ops map to prime 1 (identity element) in compute_prime_product().
LLIL_OP_PRIMES: dict[int, int] = {}


def compute_prime_product(llil_operations: list[int]) -> int:
    """
    Product of small primes assigned to each LLIL opcode.
    Position-independent: block reordering doesn't change the result.
    Mod 2^64 for fixed-size storage.

    Args:
        llil_operations: flat list of LLIL operation enum integer values
                         for all instructions in the function.
    Returns:
        UInt64 prime product, or 0 if no instructions.
    """
    if not llil_operations:
        return 0

    product = 1
    for op in llil_operations:
        prime = LLIL_OP_PRIMES.get(op, 1)
        product = (product * prime) % (2**64)

    return product


# ---------------------------------------------------------------------------
# Task 1.6: ACFG Block Features
# ---------------------------------------------------------------------------

# Instruction category indices for ACFG feature vectors
CAT_ARITHMETIC = 0
CAT_LOGIC = 1
CAT_TRANSFER = 2
CAT_CALL = 3
CAT_COMPARISON = 4
CAT_MEMORY = 5
CAT_OTHER = 6

# Maps LLIL operation integer values to category indices.
# Populated at import time by cfg.py using the real LowLevelILOperation enum.
LLIL_OP_CATEGORIES: dict[int, int] = {}


def build_block_features(
    block_llil_ops: list[list[int]],
    successors: list[list[int]],
    n: int,
) -> list[list[int]]:
    """
    Extract Gemini-style ACFG features per block.

    Args:
        block_llil_ops: per-block list of LLIL operation integer values.
                        block_llil_ops[i] is the list of ops for block i.
                        Empty list if LLIL unavailable for that block.
        successors: index-based adjacency list.
        n: number of blocks.

    Returns:
        List of [instr_count, arithmetic, logic, transfer, call, comparison,
                 memory, successor_count] per block. All values capped at 65535.
    """
    features = []
    for i in range(n):
        cats = [0, 0, 0, 0, 0, 0, 0]
        ops = block_llil_ops[i] if i < len(block_llil_ops) else []
        for op in ops:
            cat = LLIL_OP_CATEGORIES.get(op, CAT_OTHER)
            cats[cat] += 1

        instr_count = len(ops)
        features.append([
            min(instr_count, 65535),
            min(cats[CAT_ARITHMETIC], 65535),
            min(cats[CAT_LOGIC], 65535),
            min(cats[CAT_TRANSFER], 65535),
            min(cats[CAT_CALL], 65535),
            min(cats[CAT_COMPARISON], 65535),
            min(cats[CAT_MEMORY], 65535),
            min(len(successors[i]), 65535),
        ])

    return features


# ---------------------------------------------------------------------------
# Task 1.7: CFG Feature TLSH
# ---------------------------------------------------------------------------

def compute_cfg_feature_tlsh(
    bb_features: list[list[int]],
    bfs: list[int],
) -> Optional[str]:
    """
    TLSH hash of BFS-ordered per-block feature vectors.
    Captures both structure (BFS ordering) and instruction distribution.

    Returns TLSH hex string or None if too few bytes for TLSH (< 50).
    """
    import tlsh as _tlsh

    feature_bytes = bytearray()
    for idx in bfs:
        feats = bb_features[idx]
        feature_bytes.extend(struct.pack(
            '<HBBBBBBB',
            min(feats[0], 65535),
            min(feats[1], 255),
            min(feats[2], 255),
            min(feats[3], 255),
            min(feats[4], 255),
            min(feats[5], 255),
            min(feats[6], 255),
            min(feats[7], 255),
        ))

    if len(feature_bytes) < 50:
        return None

    try:
        h = _tlsh.hash(bytes(feature_bytes))
        return h if h and h != 'TNULL' else None
    except Exception:
        return None


# ---------------------------------------------------------------------------
# Task 1.8: WL-MinHash
# ---------------------------------------------------------------------------

# Pre-computed seeds for MinHash permutations.
NUM_WL_MINHASH_PERMS = 128
_WL_MINHASH_SEEDS = list(range(NUM_WL_MINHASH_PERMS))  # Seeds 0..127


def compute_wl_minhash(
    successors: list[list[int]],
    predecessors: list[list[int]],
    bb_features: list[list[int]],
    n: int,
    iterations: int = 3,
) -> list[int]:
    """
    Weisfeiler-Leman MinHash for fuzzy topology similarity.

    Initial labels: mmh3 hash of per-block ACFG feature tuple (content-aware).
    WL refinement: incorporate sorted neighbor labels at each iteration.
    MinHash: 128-permutation signature over shingle set.

    Returns list of 128 uint8 values, or [255]*128 sentinel for empty functions.
    """
    if n == 0:
        return [255] * NUM_WL_MINHASH_PERMS

    # Initial labels: hash of instruction category tuple per block
    labels = []
    for i in range(n):
        feats = bb_features[i] if i < len(bb_features) else [0] * 8
        # mmh3 with seed=0 for initial labels
        label = mmh3.hash(str(tuple(feats)), 0) & 0xFFFFFFFF
        labels.append(label)

    # Collect shingles: (iteration, label) pairs as strings for mmh3
    shingles: set[str] = set()

    # Iteration 0: individual block labels
    for label in labels:
        shingles.add(f"0:{label}")

    # WL iterations: refine labels by neighborhood aggregation
    for iteration in range(1, iterations + 1):
        new_labels = []
        for i in range(n):
            succ_labels = tuple(sorted(labels[s] for s in successors[i]))
            pred_labels = tuple(sorted(labels[p] for p in predecessors[i]))
            composite = f"{labels[i]}|{succ_labels}|{pred_labels}"
            new_label = mmh3.hash(composite, 0) & 0xFFFFFFFF
            new_labels.append(new_label)
            shingles.add(f"{iteration}:{new_label}")
        labels = new_labels

    if not shingles:
        return [255] * NUM_WL_MINHASH_PERMS

    # Compute MinHash signature using mmh3 with different seeds
    shingle_list = list(shingles)
    signature = []
    for seed in _WL_MINHASH_SEEDS:
        min_val = 0xFFFFFFFF
        for s in shingle_list:
            h = mmh3.hash(s, seed) & 0xFFFFFFFF
            if h < min_val:
                min_val = h
        # Compress to uint8 for storage
        signature.append(min_val & 0xFF)

    return signature


# ---------------------------------------------------------------------------
# Task 1.9: Packed Adjacency
# ---------------------------------------------------------------------------

def pack_adjacency(successors: list[list[int]]) -> list[int]:
    """
    Pack CFG edges as Array(UInt32).
    Each UInt32 = (source_index << 16) | target_index.
    Supports up to 65,535 blocks per function.
    """
    edges = []
    for src, targets in enumerate(successors):
        for tgt in targets:
            if src < 65536 and tgt < 65536:
                edges.append((src << 16) | tgt)
    return edges