Skip to content

Commit 1299036

Browse files
authored
doc(hash): improve README and add example (#5135) (#5614)
Improved `librz/hash/README.md` documentation to accurately reflect API usage, specifically `RzHash` vs `RzHashCfg`. Added a working C example `examples/api/hash/md5.c` demonstrating proper initialization and hashing workflow.
1 parent 0c45176 commit 1299036

File tree

5 files changed

+129
-0
lines changed

5 files changed

+129
-0
lines changed

examples/api/hash/md5.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-FileCopyrightText: 2025 Maijin <maijin21@gmail.com>
2+
// SPDX-License-Identifier: LGPL-3.0-only
3+
4+
#include <rz_hash.h>
5+
#include <stdio.h>
6+
#include <string.h>
7+
8+
int main(void) {
9+
RzHash *ctx = rz_hash_new();
10+
if (!ctx) {
11+
fprintf(stderr, "Failed to create rz_hash context\n");
12+
return 1;
13+
}
14+
15+
RzHashCfg *cfg = rz_hash_cfg_new_with_algo(ctx, "md5", NULL, 0);
16+
if (!cfg) {
17+
fprintf(stderr, "Failed to create md5 config\n");
18+
rz_hash_free(ctx);
19+
return 1;
20+
}
21+
22+
const char *data = "Hello, world!";
23+
rz_hash_cfg_update(cfg, (const ut8 *)data, strlen(data));
24+
rz_hash_cfg_final(cfg);
25+
26+
char *hex_digest = rz_hash_cfg_get_result_string(cfg, "md5", NULL, false);
27+
if (hex_digest) {
28+
printf("%s\n", hex_digest);
29+
free(hex_digest);
30+
}
31+
32+
rz_hash_cfg_free(cfg);
33+
rz_hash_free(ctx);
34+
return 0;
35+
}

examples/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
if get_option('enable_examples')
2+
executable('md5', 'api/hash/md5.c',
3+
include_directories: [platform_inc],
4+
dependencies: [rz_hash_dep],
5+
install: false
6+
)
7+
endif

librz/hash/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# RzHash
2+
3+
The Rizin hashing library, `RzHash`, offers a unified interface to various hashing algorithms, allowing other modules and users to easily compute and work with hash digests.
4+
5+
The `RzHash` structure holds all information needed for a hashing operation with a specific algorithm. Once initialized, data can be fed into the hash context incrementally. Finally, the computed hash digest can be retrieved. This design allows for efficient hashing of large data sets or streaming data without requiring the entire content to be in memory at once.
6+
7+
## What can I expect here?
8+
- For a comprehensive list of supported hash algorithms and their corresponding flags, please refer to the `rz_hash.h` header file.
9+
- A primary context `RzHash` for managing hashing operations.
10+
- Core functions for the hashing lifecycle:
11+
- `rz_hash_new()`: To initialize a hash context with a specific algorithm.
12+
- `rz_hash_update()`: To feed data to the hash context.
13+
- `rz_hash_final()`: To compute the final hash digest.
14+
- `rz_hash_free()`: To release the hash context.
15+
- Plugin-based architecture for extending supported hash algorithms.
16+
- Helper functions for one-shot hashing of common algorithms like XXH32, entropy, and ssdeep.
17+
18+
## Architecture
19+
20+
The `RzHash` library employs a plugin-based architecture to manage and provide various hashing algorithms.
21+
22+
The `RzHash` structure serves as the manager for the available hashing plugins. To perform actual hashing operations, you create an `RzHashCfg` configuration from an `RzHash` instance.
23+
24+
- **`RzHash` Context**: This is the factory and plugin manager. You initialize it once (e.g., `rz_hash_new()`).
25+
- **`RzHashCfg` Configuration**: This holds the state for a specific hashing operation (or multiple algorithms simultaneously). You create it using `rz_hash_cfg_new_with_algo(hash_ctx, "algorithm_name", ...)` or `rz_hash_cfg_new(hash_ctx)` followed by `rz_hash_cfg_configure()`.
26+
27+
- **RzHash Core Workflow**
28+
```mermaid
29+
graph TD
30+
subgraph RzHash Core Workflow
31+
C[Initialize Manager - rz_hash_new];
32+
C --> D[Create Config - rz_hash_cfg_new_with_algo];
33+
D --> E{Feed Data Chunks};
34+
E --> F[Update Hash - rz_hash_cfg_update];
35+
F --> E;
36+
E --> G[Finalize Computation - rz_hash_cfg_final];
37+
G --> H[Get Hash Digest - rz_hash_cfg_get_result];
38+
H --> I[Cleanup - rz_hash_cfg_free / rz_hash_free];
39+
end
40+
```
41+
42+
## Usage and Examples
43+
44+
### Example: Calculating an MD5 Hash
45+
46+
```c
47+
#include <rz_hash.h>
48+
#include <stdio.h>
49+
#include <string.h>
50+
51+
int main_md5_example(void) {
52+
RzHash *ctx = rz_hash_new();
53+
if (!ctx) {
54+
return 1;
55+
}
56+
57+
// Initialize the hash configuration for MD5
58+
RzHashCfg *cfg = rz_hash_cfg_new_with_algo(ctx, "md5", NULL, 0);
59+
if (!cfg) {
60+
rz_hash_free(ctx);
61+
return 1;
62+
}
63+
64+
const char *data = "Hello, world!";
65+
66+
// Update the hash context with the data
67+
rz_hash_cfg_update(cfg, (const ut8 *)data, strlen(data));
68+
69+
// Finalize the hash computation
70+
rz_hash_cfg_final(cfg);
71+
72+
// Get and print the hash digest
73+
char *hex_digest = rz_hash_cfg_get_result_string(cfg, "md5", NULL, false);
74+
if (hex_digest) {
75+
printf("%s\n", hex_digest);
76+
free(hex_digest);
77+
}
78+
79+
// Free the hash context
80+
rz_hash_cfg_free(cfg);
81+
rz_hash_free(ctx);
82+
return 0;
83+
}
84+
```

meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,8 @@ if cli_enabled
805805
endif
806806

807807
subdir('test')
808+
subdir('examples')
809+
808810

809811
install_data(
810812
'doc/fortunes.fun',

meson_options.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ option('enable_tests', type: 'boolean', value: true, description: 'Build unit te
4747
option('enable_benchmarks', type: 'boolean', value: false, description: 'Build micro-benchmarks in test/bench')
4848
option('enable_rz_test', type: 'boolean', value: true, description: 'Build rz-test executable for regression testing')
4949
option('regenerate_cmds', type: 'feature', value: 'auto', description: 'Regenerate the cmd_descs.[ch] files (requires PyYAML)')
50+
option('enable_examples', type: 'boolean', value: false, description: 'Build examples')

0 commit comments

Comments
 (0)