7
votes

Suis-je mal compris que cordes # hachage en rubis?

Je traite un groupe de données et je n'ai pas encore codé un vérificateur en double dans le processeur de données, je m'attendais donc aux doublons. J'ai exécuté la requête SQL suivante: xxx

et récupérer une liste de doublons. En regardant dans cela, je trouve que ces doublons ont plusieurs hachages. La chaîne la plus courte d'un commentaire est "[supprimé]" . Alors utilisons cela comme un exemple. Dans ma base de données, il y a neuf instances d'un commentaire étant "[supprimé]" et dans ma base de données, cela produit un hachage de 1169143752200809218 et 1738115474508091027. Le 116 est trouvé 6 fois et 173 est trouvé 3 fois. Mais, quand je l'exécute dans IRB, je reçois ce qui suit: xxx

Voici le code que j'utilise pour produire le hachage: xxx

J'ai confirmé que je ne touche pas de commentaire nulle part ailleurs dans mon code. Voici ma classe de Datamapper. xxx

suis-je corrigé en supposant que .HASH sur une chaîne retourne la même valeur à chaque fois qu'il est appelé la même chaîne?

Quelle valeur est la valeur correcte en supposant que ma chaîne consiste en "[supprimé]" ?

Y a-t-il une façon d'avoir des chaînes différentes à l'intérieur de Ruby, mais SQL les verrait comme la même chaîne? Cela semble être l'explication la plus plausible pour la raison pour laquelle cela se produit, mais je tire vraiment dans le noir.


0 commentaires

3 Réponses :


2
votes

ruby ​​fait intentionnellement string.hash produire des valeurs différentes dans différentes sessions: Pourquoi Ruby String.Hash est-il incompatible entre les machines?


0 commentaires

9
votes

Si vous exécutez

ruby ​​-e "met" [supprimé] '. hachage "

Plusieurs fois, vous remarquerez que la valeur est différente. En fait, la valeur de hachage ne reste que constante tant que votre processus de rubis est vivant. La raison en est que chaîne # hachage est ensemencé avec une valeur aléatoire. rb_str_hash (La fonction de mise en œuvre C) utilise rb_hash_start < / a> qui utilise cette graine aléatoire qui est initialisée à chaque fois que Ruby est engendré.

Vous pouvez utiliser un CRC tel que ZLIB # CRC32 à vos fins ou vous voudrez peut-être utiliser l'un des digests de message de openssl :: digest , bien que ce dernier soit surchargé depuis la détection de doublons, vous avez probablement gagné Il faut les propriétés de sécurité.


0 commentaires

6
votes

J'utilise ce qui suit pour créer des alternatives de hachage de chaîne cohérentes à travers l'heure et les processus

require 'zlib'

def generate_id(label)
  Zlib.crc32(label.to_s) % (2 ** 30 - 1)
end


2 commentaires

J'ai couru cela avec et sans la partie "% (2 ** 30 - 1)" et j'ai eu le même résultat. Soin pour expliquer pourquoi vous l'avez là-bas et ce qu'il fait?


Je voulais plafonner ma valeur de hachage à un numéro inférieur à 2 ** 30. Si vous définissez l'étiquette sur une très longue chaîne, vous devriez voir différentes valeurs renvoyées de générate_id.