diff --git a/source3/include/proto.h b/source3/include/proto.h index 199ee48..ad041b4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1121,6 +1121,12 @@ void set_remote_arch(enum remote_arch_types type); enum remote_arch_types get_remote_arch(void); const char *tab_depth(int level, int depth); int str_checksum(const char *s); +#if _FILE_OFFSET_BITS == 64 +uint64_t str_checksum64(const char *s); +#define str_checksum_inode(s) ((ino_t)str_checksum64(s)) +#else +#define str_checksum_inode(s) ((ino_t)str_checksum(s)) +#endif void zero_free(void *p, size_t size); int set_maxfiles(int requested_max); int smb_mkstemp(char *name_template); diff --git a/source3/lib/util.c b/source3/lib/util.c index 81d2a78..5b744d5 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1889,7 +1889,8 @@ const char *tab_depth(int level, int depth) } /***************************************************************************** - Provide a checksum on a string + Provide a checksum on a string (32 and 64 bit) + Uses Fowler–Noll–Vo hash function. Input: s - the null-terminated character string for which the checksum will be calculated. @@ -1897,21 +1898,42 @@ const char *tab_depth(int level, int depth) Output: The checksum value calculated for s. *****************************************************************************/ +#define FNV_INIT (0x811c9dc5) +#define FNV_PRIME (0x01000193) + int str_checksum(const char *s) { - int res = 0; - int c; - int i=0; + uint32_t res = FNV_INIT; while(*s) { - c = *s; - res ^= (c << (i % 15)) ^ (c >> (15-(i%15))); - s++; - i++; + res *= FNV_PRIME; + res ^= *s++; + } + return (int)res; +} + +#undef FNV_INIT +#undef FNV_PRIME + +#if _FILE_OFFSET_BITS == 64 +#define FNV_64_INIT (0xcbf29ce484222325ULL) +#define FNV_64_PRIME (0xcbf29ce484222325ULL) + +uint64_t str_checksum64(const char *s) +{ + uint64_t res = FNV_64_INIT; + + while(*s) { + res *= FNV_64_PRIME; + res ^= *s++; } - return(res); + return res; } +#undef FNV_64_INIT +#undef FNV_64_PRIME +#endif + /***************************************************************** Zero a memory area then free it. Used to catch bugs faster. *****************************************************************/ diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 9c61350..5b73467 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -41,7 +41,7 @@ generate_inode(SMBCCTX *context, } if (!*name) return 2; /* FIXME, why 2 ??? */ - return (ino_t)str_checksum(name); + return str_checksum_inode(name); } /*