jkent / frogfs

Fast Read-Only General-purpose File System (ESP-IDF and ESP8266_RTOS_SDK compatible)
https://frogfs.readthedocs.io
Mozilla Public License 2.0
25 stars 32 forks source link

Chosen hash function is colliding #29

Closed X-Ryl669 closed 2 years ago

X-Ryl669 commented 2 years ago

Currently chosen hash function is colliding. In effect, any char X followed by Y so that Y = X+33 gives the same result as X+1 followed by X. And since a path is very likely to have successive char with a distance of 33 between them, this is going to happen frequently. For example, "2S" gives the same hash as "32"

Replacing:

static uint32_t hash_path(const char *path)
{
    uint32_t hash = 5381;
    const uint8_t *p = (uint8_t *)path;

    while (*p) {
        /* hash = hash * 33 + *p */
        hash = (hash << 5) + hash + *p;
        p++;
    }

    return hash;
}

by

static uint32_t hash_path(const char *path)
{
    uint32_t hash = 5381;
    const uint8_t *p = (uint8_t *)path;

    while (*p) {
        /* hash = hash * 257 + *p */
        hash = (hash << 8) + hash + *p;
        p++;
    }

    return hash;
}

will solve this issue since there is no char that's 257 higher than another.

jkent commented 2 years ago

Thank you! I'm not sure where I pulled the original hashing function from, but this does make way more sense. Would you mind updating your pull request and increment ESPFS_VERSION_MAJOR?

jkent commented 2 years ago

Resolved, thank you again.