hash: add jenkins non-cryptographic hash (#6121)

This commit is contained in:
Shessaanand Siva Sivamurugan 2026-04-01 23:12:23 +05:30 committed by GitHub
parent 2fe2696ac3
commit 7ad49c41c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 133 additions and 1 deletions

1
.gitignore vendored
View file

@ -141,3 +141,4 @@ dist/windows/Output
# Core files generated by OpenBSD
*.core
.venv
venv/

View file

@ -81,6 +81,7 @@ hash_plugins_list = [
'crca_crc64we',
'crca_crc64xz',
'crca_crc64iso',
'jenkins',
'xor8',
'xor16',
'xxhash32',
@ -130,6 +131,7 @@ rz_hash_sources = [
'p/algo_murmur3_x64_128.c',
'p/algo_murmur3_x86_32.c',
'p/algo_murmur3_x86_128.c',
'p/algo_jenkins.c',
'p/algo_xor8.c',
'p/algo_xor16.c',
'p/algo_xxhash32.c',

115
librz/hash/p/algo_jenkins.c Normal file
View file

@ -0,0 +1,115 @@
// SPDX-FileCopyrightText: 2026 shessaanand <shessaasiva@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_hash.h>
#include <rz_util/rz_assert.h>
#include <rz_lib.h>
typedef ut32 RzJenkins;
#define RZ_HASH_JENKINS_DIGEST_SIZE 4
#define RZ_HASH_JENKINS_BLOCK_LENGTH 0
static void *plugin_jenkins_context_new() {
return RZ_NEW0(RzJenkins);
}
static void plugin_jenkins_context_free(void *context) {
free(context);
}
static RzHashSize plugin_jenkins_digest_size(void *context) {
return RZ_HASH_JENKINS_DIGEST_SIZE;
}
static RzHashSize plugin_jenkins_block_size(void *context) {
return RZ_HASH_JENKINS_BLOCK_LENGTH;
}
static bool plugin_jenkins_init(void *context) {
rz_return_val_if_fail(context, false);
RzJenkins *ctx = (RzJenkins *)context;
*ctx = 0;
return true;
}
static bool plugin_jenkins_update(void *context, const ut8 *data, ut64 size) {
rz_return_val_if_fail(context, false);
if (size > 0) {
rz_return_val_if_fail(data, false);
}
RzJenkins *ctx = (RzJenkins *)context;
ut32 hash = *ctx;
for (ut64 i = 0; i < size; ++i) {
hash += data[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
*ctx = hash;
return true;
}
static bool plugin_jenkins_final(void *context, ut8 *digest) {
rz_return_val_if_fail(context && digest, false);
RzJenkins *ctx = (RzJenkins *)context;
ut32 hash = *ctx;
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
rz_write_be32(digest, hash);
return true;
}
static bool plugin_jenkins_small_block(const ut8 *data, ut64 size, ut8 **digest, RzHashSize *digest_size) {
rz_return_val_if_fail(digest, false);
if (size > 0) {
rz_return_val_if_fail(data, false);
}
ut8 *dgst = malloc(RZ_HASH_JENKINS_DIGEST_SIZE);
if (!dgst) {
return false;
}
RzJenkins ctx = { 0 };
plugin_jenkins_init(&ctx);
plugin_jenkins_update(&ctx, data, size);
plugin_jenkins_final(&ctx, dgst);
*digest = dgst;
if (digest_size) {
*digest_size = RZ_HASH_JENKINS_DIGEST_SIZE;
}
return true;
}
RzHashPlugin rz_hash_plugin_jenkins = {
.name = "jenkins",
.license = "LGPL3",
.author = "shessaanand",
.description = "Jenkins non-cryptographic hash",
.support_hmac = false,
.context_new = plugin_jenkins_context_new,
.context_free = plugin_jenkins_context_free,
.digest_size = plugin_jenkins_digest_size,
.block_size = plugin_jenkins_block_size,
.init = plugin_jenkins_init,
.update = plugin_jenkins_update,
.final = plugin_jenkins_final,
.small_block = plugin_jenkins_small_block,
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_HASH,
.data = &rz_hash_plugin_jenkins,
.version = RZ_VERSION
};
#endif

File diff suppressed because one or more lines are too long

View file

@ -203,6 +203,14 @@ ERROR: rz-hash: error, input string is not a number
EOF
RUN
NAME=rz-hash -a jenkins -s jenkinshash
TOOL=rz-hash
ARGS=-a jenkins -s jenkinshash
EXPECT=<<EOF
string: 0x00000000-0x0000000b jenkins: c652f619
EOF
RUN
NAME=rz-hash -L
TOOL=rz-hash
ARGS=-L
@ -273,6 +281,7 @@ ____h_ fletcher16 LGPL3 deroad Fletcher16 check
____h_ fletcher32 LGPL3 deroad Fletcher32 checksum
____h_ fletcher64 LGPL3 deroad Fletcher64 checksum
____h_ fletcher8 LGPL3 deroad Fletcher8 checksum
____h_ jenkins LGPL3 shessaanand Jenkins non-cryptographic hash
____hm keccak-256 BSD-3 Andrey Jivsov KECCAK-256 cryptographic hash
____hm keccak-384 BSD-3 Andrey Jivsov KECCAK-384 cryptographic hash
____hm keccak-512 BSD-3 Andrey Jivsov KECCAK-512 cryptographic hash
@ -750,6 +759,7 @@ string: 0x00000000-0x00000005 fletcher16: computed hash doesn't match the expect
string: 0x00000000-0x00000005 fletcher32: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 fletcher64: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 fletcher8: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 jenkins: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 keccak-256: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 keccak-384: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 keccak-512: computed hash doesn't match the expected one

View file

@ -70,6 +70,7 @@ static hash_data_t hashes_to_test[] = {
{ INDATA("password"), .algo = "fletcher16", .expected = "7698" },
{ INDATA("password"), .algo = "fletcher32", .expected = "cda87d23" },
{ INDATA("password"), .algo = "fletcher64", .expected = "e7d0e5d75732594b" },
{ INDATA("password"), .algo = "jenkins", .expected = "08d63509" },
{ INDATA("password"), .algo = "adler32", .expected = "7403910f" },
{ INDATA("password"), .algo = "crc8smbus", .expected = "4f" },
{ INDATA("password"), .algo = "crc8cdma2000", .expected = "d6" },