logo

Acerca de

Bienvenido a mi blog, el sitio perfecto para mis inquietudes, experiencias e idas de olla sobre temas de hoy en día.

Historia al azar

Categorías

Últimas entradas

Últimos comentarios

Enlaces

Meta

photo Luis PeraltaEstado Jabber
Ziritione
Castellón Spain
39.997638, -0.064030

Sindica

Sindícame, por cortesía del subliminal Atom.

29 Enero 2008

Los hashes o resúmenes FNV (de Fowler / Noll / Vo) son útiles por varias razones:

  • Es muy rápido generarlos
  • El tamaño del hash es fácilmente manipulable
  • Se portan muy bien, es decir, producen pocas colisiones

Pues hoy necesitaba usarlos con mi querido Python y curiosamente nadie lo había implementado. Así que no me ha quedado más remedio que ponerme (no sé quién me ha dicho esta tarde que eso sería sólo un algoritmo, que no tendría complicación... en cuanto lo recuerde se va a acordar). Por si a alguien le viene bien:

def FNV1a32(key):
    fnv_prime = long(0x1000193)
    hash = long(0x811C9DC5)
    for i in range(len(key)):
      hash ^= ord(key[i])
      hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24)
    return (hash & 0x00000000ffffffffL)

def FNV132(key):
    fnv_prime = long(0x1000193)
    hash = long(0x811C9DC5)
    for i in range(len(key)):
      hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24)
      hash ^= ord(key[i])
    return (hash & 0x00000000ffffffffL)

La diferencia entre FNV132 y FNV1a32 es el orden en el que se hace la multiplicación. Y aquí sólo he puesto los métodos que calculan el hash de 32 bits, en la referencia de arriba tenéis cómo hacer para generarlos variables (escoger un buen primo inicial, fnv_prime, y un valor inicial del hash, hash, adecuados y quedarnos sólo con la parte del resultado que nos interese).