Add support for fletcher8, 16, 32 and 64 hash algorithms ##hash

This commit is contained in:
radare 2019-06-06 16:53:58 -04:00 committed by GitHub
parent 1fd2405161
commit 1ccb555b9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 5 deletions

View File

@ -11,7 +11,7 @@ endif
endif
DEPS=r_util
OBJS=state.o hash.o hamdist.o crca.o
OBJS=state.o hash.o hamdist.o crca.o fletcher.o
OBJS+=entropy.o calc.o adler32.o luhn.o
ifeq ($(HAVE_LIB_SSL),1)

View File

@ -1,7 +1,6 @@
/* radare2 - LGPL - Copyright 2009-2018 pancake */
#include "r_hash.h"
/* radare2 - LGPL - Copyright 2009-2019 pancake */
#include <r_hash.h>
#define HANDLE_CRC_PRESET(rbits, aname) \
do { \
@ -46,6 +45,26 @@ R_API int r_hash_calculate(RHash *ctx, ut64 algobit, const ut8 *buf, int len) {
memcpy (ctx->digest, &res, R_HASH_SIZE_XXHASH);
return R_HASH_SIZE_XXHASH;
}
if (algobit & R_HASH_FLETCHER8) {
ut8 res = r_hash_fletcher8 (buf, len);
memcpy (ctx->digest, &res, R_HASH_SIZE_FLETCHER8);
return R_HASH_SIZE_FLETCHER8;
}
if (algobit & R_HASH_FLETCHER16) {
ut16 res = r_hash_fletcher16 (buf, len);
memcpy (ctx->digest, &res, R_HASH_SIZE_FLETCHER16);
return R_HASH_SIZE_FLETCHER16;
}
if (algobit & R_HASH_FLETCHER32) {
ut32 res = r_hash_fletcher32 (buf, len);
memcpy (ctx->digest, &res, R_HASH_SIZE_FLETCHER32);
return R_HASH_SIZE_FLETCHER32;
}
if (algobit & R_HASH_FLETCHER64) {
ut64 res = r_hash_fletcher64 (buf, len);
memcpy (ctx->digest, &res, R_HASH_SIZE_FLETCHER64);
return R_HASH_SIZE_FLETCHER64;
}
if (algobit & R_HASH_ADLER32) {
ut32 res = r_hash_adler32 (buf, len);
memcpy (ctx->digest, &res, R_HASH_SIZE_ADLER32);

87
libr/hash/fletcher.c Normal file
View File

@ -0,0 +1,87 @@
/* radare2 - LGPL - Copyright 2019 pancake */
#include <r_hash.h>
R_API ut16 r_hash_fletcher8(const ut8 *d, size_t length) {
size_t i;
ut16 a = 0;
ut16 b = 0;
for (i = 0; i < length; i++) {
a += d[i];
a = (a & 0xff) + (a >> 8);
b += a;
b = (b & 0xff) + (b >> 8);
}
return a << 8 | b;
}
R_API ut16 r_hash_fletcher16(const ut8 *data, size_t len) {
ut32 c0, c1;
size_t i;
for (c0 = c1 = 0; len >= 5802; len -= 5802) {
for (i = 0; i < 5802; ++i) {
c0 = c0 + *data++;
c1 = c1 + c0;
}
c0 %= 0xff;
c1 %= 0xff;
}
for (i = 0; i < len; ++i) {
c0 += *data++;
c1 += c0;
}
c0 %= 0xff;
c1 %= 0xff;
return (c1 << 8 | c0);
}
R_API ut32 r_hash_fletcher32(const ut8 *data, size_t len) {
ut32 c0, c1;
size_t i;
ut8 word[sizeof (ut16)];
for (c0 = c1 = 0; len >= 360; len -= 360) {
for (i = 0; i < 360; i++) {
size_t left = 360 - i;
memset (word, 0, sizeof (word));
memcpy (word, data, R_MIN (sizeof (word), left));
ut16 w = r_read_le16 (word);
c0 += w;
c1 += c0;
data += 2;
}
c0 %= UT16_MAX;
c1 %= UT16_MAX;
}
for (i = 0; i < len; i++) {
size_t left = 360 - i;
memset (word, 0, sizeof (word));
memcpy (word, data, R_MIN (sizeof (word), left));
ut16 w = r_read_le16 (word);
c0 += w;
c1 += c0;
data += 2;
}
c0 %= UT16_MAX;
c1 %= UT16_MAX;
return (c1 << 16 | c0);
}
R_API ut64 r_hash_fletcher64(const ut8 *addr, size_t len) {
const ut8 *p32 = addr;
const ut8 *p32end = addr + len;
ut32 lo32 = 0;
ut32 hi32 = 0;
ut8 word[sizeof (ut32)];
while (p32 < p32end) {
size_t left = p32end - p32;
memset (word, 0, sizeof (word));
memcpy (word, p32, R_MIN (sizeof (word), left));
ut32 w = r_read_le32 (word);
lo32 += w;
p32 += sizeof (ut32);
hi32 += lo32;
}
return ((ut64)hi32 << 32) | lo32;
}

View File

@ -1,4 +1,4 @@
/* radare2 - LGPL - Copyright 2007-2018 pancake */
/* radare2 - LGPL - Copyright 2007-2019 pancake */
#include <r_hash.h>
#include "r_util.h"
@ -35,6 +35,11 @@ static const struct {
// {"punycode", R_HASH_PUNYCODE},
{ "luhn", R_HASH_LUHN },
{ "fletcher8", R_HASH_FLETCHER8 },
{ "fletcher16", R_HASH_FLETCHER16 },
{ "fletcher32", R_HASH_FLETCHER32 },
{ "fletcher64", R_HASH_FLETCHER64 },
{ "crc8smbus", R_HASH_CRC8_SMBUS },
#if R_HAVE_CRC8_EXTRA
{ /* CRC-8/CDMA2000 */ "crc8cdma2000", R_HASH_CRC8_CDMA2000 },

View File

@ -3,6 +3,7 @@ r_hash_sources = [
'calc.c',
'crca.c',
'entropy.c',
'fletcher.c',
'hamdist.c',
'hash.c',
'luhn.c',

View File

@ -77,6 +77,11 @@ typedef ut32 utcrc;
#endif
#define UTCRC_C(x) ((utcrc)(x))
R_API ut16 r_hash_fletcher8(const ut8 *d, size_t length);
R_API ut16 r_hash_fletcher16(const ut8 *data, size_t len);
R_API ut32 r_hash_fletcher32(const ut8 *data, size_t len);
R_API ut64 r_hash_fletcher64(const ut8 *addr, size_t len);
typedef struct {
utcrc crc;
ut32 size;
@ -269,6 +274,10 @@ typedef struct r_hash_seed_t {
#define R_HASH_SIZE_XORPAIR 2
#define R_HASH_SIZE_HAMDIST 1
#define R_HASH_SIZE_LUHN 1
#define R_HASH_SIZE_FLETCHER8 1
#define R_HASH_SIZE_FLETCHER16 2
#define R_HASH_SIZE_FLETCHER32 4
#define R_HASH_SIZE_FLETCHER64 8
#define R_HASH_NBITS (8*sizeof(ut64))
@ -364,6 +373,10 @@ enum HASH_INDICES {
R_HASH_IDX_CRC64_ISO,
#endif /* #if R_HAVE_CRC64_EXTRA */
R_HASH_IDX_FLETCHER8,
R_HASH_IDX_FLETCHER16,
R_HASH_IDX_FLETCHER32,
R_HASH_IDX_FLETCHER64,
R_HASH_NUM_INDICES
};
@ -387,6 +400,10 @@ enum HASH_INDICES {
#define R_HASH_BASE91 (1ULL << R_HASH_IDX_BASE91)
#define R_HASH_PUNYCODE (1ULL << R_HASH_IDX_PUNYCODE)
#define R_HASH_LUHN (1ULL << R_HASH_IDX_LUHN)
#define R_HASH_FLETCHER8 (1ULL << R_HASH_IDX_FLETCHER8)
#define R_HASH_FLETCHER16 (1ULL << R_HASH_IDX_FLETCHER16)
#define R_HASH_FLETCHER32 (1ULL << R_HASH_IDX_FLETCHER32)
#define R_HASH_FLETCHER64 (1ULL << R_HASH_IDX_FLETCHER64)
#define R_HASH_CRC8_SMBUS (1ULL << R_HASH_IDX_CRC8_SMBUS)
#if R_HAVE_CRC8_EXTRA