2011-07-21 11 views
24

Hoy lo encontramos en una aplicación que estamos implementando en muchos servidores. Estaba almacenando algunas cadenas para almacenarlas en un almacén de claves/valores compartidos. El método .hash de String está devolviendo enteros diferentes según el servidor. ¿Alguna idea de por qué? Tenga en cuenta que estoy interesado en por qué; no es posible evitarlo.¿Por qué Ruby String.hash no es uniforme en todas las máquinas?

Ejemplo:

server1 $ ruby -v 
ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux] 

server1 $ irb 
irb(main):001:0> "test".hash 
=> 4146582576695053125 


server2 $ ruby -v 
ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux] 

server2 $ irb 
"test".hash 
=> 3479379392688537032 

Estas máquinas son instancias de EC2 con las mismas especificaciones y construir.

+0

Nos preguntamos si también puede mostrar el valor de 'RUBY_VERSION' dentro de' irb'. – GarlicFries

+0

Por ejemplo: 'ruby-1.9.2-p290: 002> RUBY_VERSION => "1.9.2"' ' – GarlicFries

+0

IRB (principales): 001: 0> RUBY_VERSION => "1.9.2"' para ambos – Brad

Respuesta

23

Desde un desarrollador de Ruby en el Ruby forum:

Se pretende. Ruby 1.9 utiliza explícitamente la semilla aleatoria local de sesión en para calcular un hash para cadenas (y algunos otros objetos).

Esto se debe a la implementación de objetos # hash es diferente entre versiones (como 1.9.1 y 1.9.2) e implementaciones (como JRuby, Rubinius, IronRuby, y así sucesivamente). Queremos que la gente escriba el código portable alrededor de Object # hash, así que lo hicimos.

Deberías usar Digest :: SHA256 o algunas otras rutinas de resumen cuando quieres un poco de valor hash (resumen del mensaje).

y seguimiento de otro dev:

Además, ayuda a evitar algunos ataques de denegación de servicio, tales como cientos registro y miles de usuarios con nombres de usuario que tienen el mismo código hash .

+0

Sí, mi "solución" era usar Digest, pero esto parecía extraño proveniente de más de un fondo de Java. – Brad

Cuestiones relacionadas