R_HASH(3)

πŸ’– R_HASH(3) β€” the radare2 hashing & checksum library, bestie edition πŸ’–

okay so real talk, this is a page from the Library Functions Manual, and it's all about r_hash β€” the hashing and checksum library for radare2. grab a strawberry πŸ“ and let's get into it.


✨ NAME ✨

r_hash β€” Hashing and checksum library for radare2. that's the whole vibe. it hashes. it checksums. it slays. πŸ’…


🌈 SYNOPSIS 🌈

first things first, you gotta pull in the header:

#include <r_hash.h>

then the two main-character functions:

RHash *
r_hash_new(bool rst, ut64 flags);

void
r_hash_free(RHash *ctx);

and a lil note for u: the following are representative function prototypes used throughout the library and examples in this manual page; more prototypes are provided in the header. so like, this isn't the whole guest list, just the VIPs. πŸ‘‘


πŸ¦‹ DESCRIPTION πŸ¦‹

The r_hash library implements many common hashing and checksum primitives (MD4/MD5/SHA family, CRCs, Adler, SipHash, xxHash, ssdeep, etc.), plus analysis helpers such as entropy and hamming distance. like… it does SO much. it's giving overachiever. πŸ’€

The main structure is struct r_hash_t, which stores intermediate contexts for several algorithms and an aligned digest buffer. that's your home base, bestie. everything lives in there.


πŸŽ€ INITIALIZATION πŸŽ€

Initialization and cleanup functions handle allocation and freeing of a hash context. The rst argument controls whether the context is reset between operations and flags selects which algorithms to prepare.

RHash * r_hash_new(bool rst, ut64 flags)
void r_hash_free(RHash *ctx)

Typical usage in applications: create a context once with the algorithms you need (for example R_HASH_MD5 | R_HASH_SHA256) and reuse it for multiple inputs to avoid repeated allocations, calling r_hash_free when done. reuse the context, bestie β€” allocating over and over is not the move. ✨

🫢 and PLEASE call r_hash_free when you're done. we do not leak memory in this house.

πŸ‘‘ CORE OPERATIONS πŸ‘‘

Core single-shot and multi-algorithm operations compute digests and expose helpers to map names and sizes.

ut8 * r_hash_do_md5(RHash *ctx, const ut8 *input, int len)
ut8 * r_hash_do_sha1(RHash *ctx, const ut8 *input, int len)
ut8 * r_hash_do_sha256(RHash *ctx, const ut8 *input, int len)
int r_hash_calculate(RHash *ctx, ut64 algobit, const ut8 *input, int len)
const char * r_hash_name(ut64 bit)
int r_hash_size(ut64 bit)
char * r_hash_tostring(RHash *ctx, const char *name, const ut8 *data, int len)

Use r_hash_calculate when you want to compute several algorithms into the context's digest buffer at once; it returns the digest size in bytes for the requested algorithm bit. Use r_hash_name and r_hash_size to print properly sized hex dumps. no more guessing how many bytes to print, we love a correctly sized hex dump. 😌


🧚 CHECKSUMS AND ANALYSIS 🧚

The library provides many lightweight checksum and analysis helpers useful when scanning binary buffers or computing features for heuristics (entropy, parity, xor, Adler32, xxhash, ssdeep fingerprinting, etc.).

ut32 r_hash_adler32(const ut8 *buf, int len)
ut32 r_hash_xxhash(const ut8 *buf, ut64 len)
ut8 r_hash_xor(const ut8 *b, ut64 len)
double r_hash_entropy(const ut8 *data, ut64 len)
char * r_hash_ssdeep(const ut8 *buf, size_t len)

In radare2, these helpers are used for file heuristics (for example computing entropy to detect packed or compressed regions) and for concise diagnostics (e.g., showing a ssdeep fuzzy hash for similarity). r_hash_entropy_fraction returns a normalized value [0..1] used by UI code. entropy really said "let me tell u if this binary is sus" and honestly? iconic. πŸ”₯


πŸ’œ ADVANCED / INCREMENTAL USAGE πŸ’œ

For streaming or incremental hashing (hashing a large file chunk-by-chunk), the library exposes begin/end primitives and r_hash_do_spice for repeated re-hashing with a seed (used by rahash2 to perform iterative strengthening).

void r_hash_do_begin(RHash *ctx, ut64 flags)
void r_hash_do_end(RHash *ctx, ut64 flags)
void r_hash_do_spice(RHash *ctx, ut64 algo, int loops, RHashSeed *seed)
ut8 * r_hash_do_hmac_sha256(RHash *ctx, const ut8 *input, int len, const ut8 *key, int klen)

A common pattern (see rahash2 and r_hash usage in libr/main/rahash2.c) is:

r_hash_do_begin (ctx, R_HASH_SHA256);
// feed chunks with r_hash_calculate or algorithm-specific functions
r_hash_calculate (ctx, R_HASH_SHA256, chunk, chunk_len);
r_hash_do_end (ctx, R_HASH_SHA256);
// result is in ctx->digest

When you need to perform key-based MACs, use r_hash_do_hmac_sha256 to obtain the HMAC-SHA256 digest in a single call. one call, one digest, zero drama. πŸ’…


🌸 PRACTICAL EXAMPLES 🌸

The examples below show real-life usage patterns found in libr/main/rahash2.c, libr/core/cbin.c and libr/core/cmd_print.inc.c. like, these are literally pulled from the wild. not me getting emotional over real code πŸ₯Ή

Example: compute chunked hashes of a file (adapted from rahash2)

// open file and create ctx with the chosen algorithm bit
RHash *ctx = r_hash_new (true, R_HASH_SHA256);
// incremental mode: begin, feed chunks, end
r_hash_do_begin (ctx, R_HASH_SHA256);
for (offset = 0; offset < file_size; offset += block_size) {
    int len = MIN (block_size, file_size - offset);
    r_io_pread_at (io, offset, buf, len); // read into buf
    r_hash_calculate (ctx, R_HASH_SHA256, buf, len);
}
r_hash_do_end (ctx, R_HASH_SHA256);
// ctx->digest contains the SHA-256 result (32 bytes)
char *s = r_hash_tostring (ctx, "sha256", ctx->digest, 32);
printf ("sha256: %s0, s);
free (s);
r_hash_free (ctx);

Example: compute entropy and display as a 0..255 value (used by cmd_print)

double ent = r_hash_entropy_fraction (data, data_size);
ut8 visual = (ut8)(ent * 255);
printf ("entropy_frac=%.3f, visual=%u0, ent, visual);

Example: compare a computed digest against an expected one (pattern from rahash2)

RHash *ctx = r_hash_new (true, R_HASH_MD5);
r_hash_calculate (ctx, R_HASH_MD5, buf, len);
if (!memcmp (ctx->digest, expected_digest, 16)) {
    puts ("match");
} else {
    puts ("mismatch");
}
r_hash_free (ctx);

Example: produce a ssdeep fuzzy hash string for a buffer

char *fuzzy = r_hash_ssdeep (buf, len);
if (fuzzy) {
    printf ("ssdeep: %s0, fuzzy);
    free (fuzzy);
}

⭐ NOTES ⭐

Function names and bitmasks are declared in libr/include/r_hash.h. Pick the exact algorithm using r_hash_name_to_bits/r_hash_name helpers when mapping user strings to bit flags. iykyk β€” string in, bitmask out, that's the whole trick. ✨

Many radare2 internal users create a single RHash and call r_hash_calculate repeatedly; prefer incremental do_begin/do_end when hashing very large streams to avoid copying large buffers into memory. fr fr, do NOT be out here memcpy-ing giant buffers when begin/end exists. your RAM will thank u. 😭


🫢 SEE ALSO 🫢

go read those next bestie, they're all in the same friend group πŸ’–


and that's the whole page!! this one ships from Debian, dated September 21, 2025. πŸ’–βœ¨ hashing is literally so fun when u have the right manual, no cap. go forth and r_hash_calculate, my love. πŸŽ€πŸ¦‹πŸ’…

πŸ“¦ where this page comes from