2009-04-16 16 views
6

1) Con el propósito de una colisión hash muy baja, ¿puedo salirse con la suya simplemente usando la mitad de los 128 bits de un sha1 en lugar de lidiar con el sha1 mismo? Entiendo que esto no es adecuado para hashes criptográficos, pero solo necesito los hash para las claves de la tabla hash.¿Está bien para usar solo 64 bits de sha1 hash como id?

2) El tiempo de cálculo no es una prioridad, y además estoy recopilando datos muy pequeños. En particular, voy a tomar 2 o 3 hashes de 64 bits y mezclarlos para obtener otro hash de 64 bits. ¿Hay una mejor opción que sha1 para este propósito? Nuevamente, las colisiones deberían ser muy poco probables.

3) Soy un sql newb. ¿Es una buena idea usar hashes de 64 bits como id en sql? ¿Los id de 64 bits causarán problemas de rendimiento en sqlite o postgres? Voy a necesitar coordinar los datos en varias bases de datos (incluido un índice Lucene), así que pensé que debería tratar con los hash directamente en las tablas en lugar de molestar con los identificadores autoincormentados (que solo serían significativos en un db, no en todas las tiendas de datos). Creo que 64 bits es un buen compromiso: lo suficientemente grande para colisiones poco probables, pero ahorra espacio (¿y tiempo de búsqueda?).

4) ¿Qué hay de CRC-64? ¿Eso produce una distribución lo suficientemente aleatoria?

Respuesta

6

Si tiene pocos registros, es casi seguro que nunca tendrá una colisión hash en 64 bits. Probablemente caerá en esta categoría.

Hay debe haber ningún problema con el recorte por un hash criptográfico como sha1, porque si hubiera estructura interna en el hash entonces no sería lo suficientemente bueno para ser un hash criptográfico, y si no hay estructura, entonces cualquier subconjunto de los bits debe ser bastante aleatorio. Tenga en cuenta que solo estoy hablando de usar eso para ID, ¡no para fines criptográficos!

Pero realmente, ¿su SQL no tiene algún tipo de GUID? Y si lo hace, ¿por qué no usarlo?

+0

Supongo que GUID/UUID es más o menos lo que quiero. No estoy seguro si el soporte de sqlite es adecuado, así que investigaré eso. Como dije, soy un recién llegado de sql. – Jegschemesch

+0

Sqlite3 se puede ampliar fácilmente para admitir UUID, y lo he hecho con éxito en una aplicación para iPhone. –

+0

estoy de acuerdo en esta respuesta. Tengo una tabla llena de cientos de millones de filas y utilizo los primeros 64 bits como clave entera sin definir en lugar de un hash sha1 como cadena por motivos de rendimiento. con 350 millones de filas tuve algunas colisiones con 56 bits. siempre combino la clave hash de 64 bits con su fecha para que tanto hashkey como date tengan que coincidir. Usando ese método, solo tengo 30 millones de filas por día que pueden causar colisiones, reduciendo en gran medida la posibilidad de que ocurra a largo plazo. una colisión conduciría a una paz única de información mal colocada, en mi caso vale la pena el ahorro. – bhelm

0

Si el tiempo de cálculo no es importante ¿por qué no ir a los 128 bits enteros? ¿Hay alguna razón real para elegir 64 bits además de posibles problemas de almacenamiento? (y luego 8 bytes adicionales no te van a matar con un almacenamiento tan económico)

64 bits frente a 128 bits no causarán problemas de velocidad en SQLite, no estoy seguro acerca de mySQL.

+0

Creo que al usar datos hash aleatorios como clave, la mayoría de los sistemas de bases de datos son más eficientes con las operaciones de búsqueda y unión si la clave se ajusta al entero nativo de la máquina en lugar de a las cadenas. – bhelm

3

Sus claves necesitarán absoluta singularidad no alta probabilidad de singularidad Sugiero usar GUID en lugar de hash para las claves de compatibilidad entre bases de datos. Genere el hash como un mecanismo de búsqueda rápida, puede tener un índice no exclusivo en esto, pero en el caso de una colisión tendrá que comparar los datos reales para asegurarse de que son los mismos. Al sincronizar sus bases de datos, puede verificar el hash (usando rápidamente el índice) y si encuentra una colisión, entonces resuelva si los datos son los mismos y, por lo tanto, los GUID deben resolverse. Si no hay una colisión, simplemente actualice cualquier base de datos que necesite la entrada faltante e inserte usando el GUID de la otra base de datos.

Yo también veo un punto en la creación de su propio hash de hashes para ahorrar espacio. Si ya tiene los otros hashes, simplemente úselos (adjuntar, no repetir). Si no, simplemente use una función hash estándar como MD5 o SHA1 y almacene los datos resultantes.

+1

¿Pero por qué necesito la unicidad absoluta? ¿No estamos hablando de MUY alta probabilidad? 1 en 2^128 posibilidad de que dos elementos tengan el mismo hash, ¿verdad? ¿No sería mejor que nos preocupemos por ser golpeados por un meteoro? ¿O MD5 y sha1 no se distribuyen de forma aleatoria? – Jegschemesch

+0

Ah, creo que estamos hablando el uno del otro porque era ignorante de GUID/UUID mientras parecía asumir que no era así. Pero los GUID tampoco son ABSOLUTAMENTE únicos, ¿verdad? – Jegschemesch

+0

Sí. Los identificadores únicos globales (o universalmente únicos) son absolutamente únicos. El algoritmo de generación asegura que no hay dos máquinas que produzcan los mismos identificadores. Mi punto es que si lo está usando como clave principal no puede tolerar ni siquiera una colisión, sin importar cuán raro sea. – tvanfosson

2

Con hashes de 64 bits, tiene un 1% de posibilidades de una colisión con 6.1 × 10 registros. (Para otras combinaciones, vea Wikipedia page on the Birthday problem.) Puede tirar los primeros 64 bits, o el último, de cada segundo bit, no hace ninguna diferencia en las propiedades del hash.

Cuestiones relacionadas