Comment créer un HashCode dans .net (c #) pour une chaîne pouvant être stockée dans une firebase database?

Pour citer des lignes direcsortingces et des règles pour GetHashCode par Eric Lippert:

Règle: les consommateurs de GetHashCode ne peuvent pas compter sur sa stabilité dans le temps ou dans les domaines d’application

Supposons que vous ayez un object Client contenant un groupe de champs tels que Nom, Adresse, etc. Si vous créez deux objects de ce type avec exactement les mêmes données dans deux processus différents, ils ne doivent pas renvoyer le même code de hachage. Si vous créez un tel object mardi dans un processus, fermez-le et exécutez à nouveau le programme mercredi, les codes de hachage peuvent être différents.

Cela a mordu les gens dans le passé. La documentation de System.Ssortingng.GetHashCode note spécifiquement que deux chaînes identiques peuvent avoir des codes de hachage différents dans différentes versions du CLR, et en fait elles le font. Ne stockez pas les hachages de chaînes dans les bases de données et attendez-vous à ce qu’elles soient les mêmes pour toujours, car elles ne le seront pas.

Alors, quelle est la bonne façon de créer un HashCode d’une chaîne que je peux stocker dans une firebase database?

(S’il vous plaît dites-moi que je ne suis pas la première personne à avoir laissé ce bug dans le logiciel que j’ai écrit!)

Cela dépend des propriétés que vous voulez que ce hash ait. Par exemple, vous pourriez simplement écrire quelque chose comme ceci:

public int HashSsortingng(ssortingng text) { // TODO: Determine nullity policy. unchecked { int hash = 23; foreach (char c in text) { hash = hash * 31 + c; } return hash; } } 

Tant que vous documentez que c’est ainsi que le hachage est calculé, c’est valable. Ce n’est en aucune manière cryptographiquement sécurisé ou quelque chose comme ça, mais vous pouvez le conserver sans aucun problème. Deux chaînes absolument égales au sens ordinal (c’est-à-dire sans égalité culturelle, etc. appliquées exactement de la même manière caractère par caractère) produiront le même hachage avec ce code.

Les problèmes surviennent lorsque vous utilisez un hachage non documenté – c’est-à-dire quelque chose qui obéit à GetHashCode() mais qui n’est en aucun cas garanti de restr identique d’une version à l’autre … comme ssortingng.GetHashCode() .

Ecrire et documenter votre propre hash comme celui-ci, c’est un peu comme dire: “Cette information sensible est hachée avec MD5 (ou autre)”. Tant que c’est un hachage bien défini, ça va.

EDIT: D’autres réponses ont suggéré d’utiliser des hachages cryptographiques tels que SHA-1 ou MD5. Je dirais que jusqu’à ce que nous sachions qu’il existe un besoin de sécurité cryptographique plutôt que de stabilité, il ne sert à rien de passer par la conversion de la chaîne en un tableau d’octets et de le hacher. Bien sûr, si le hachage est destiné à être utilisé pour tout ce qui concerne la sécurité, un hachage standard est exactement ce que vous devriez atteindre. Mais cela n’a été mentionné nulle part dans la question.

Voici une réimplémentation de la manière actuelle .NET calcule le code de hachage des chaînes pour les systèmes 64 bits . Cela n’utilise pas de pointeurs comme le vrai GetHashCode() donc il sera légèrement plus lent, mais cela le rend plus résistant aux modifications internes des ssortingng , cela donnera un code de hachage plus dissortingbué que la version de Jon Skeet temps de recherche dans les dictionnaires.

 public static class SsortingngExtensionMethods { public static int GetStableHashCode(this ssortingng str) { unchecked { int hash1 = 5381; int hash2 = hash1; for(int i = 0; i < str.Length && str[i] != '\0'; i += 2) { hash1 = ((hash1 << 5) + hash1) ^ str[i]; if (i == str.Length - 1 || str[i+1] == '\0') break; hash2 = ((hash2 << 5) + hash2) ^ str[i+1]; } return hash1 + (hash2*1566083941); } } } 

La réponse est d’écrire simplement votre propre fonction de hachage. Vous pouvez trouver des sources pour certains en suivant les liens dans les commentaires à l’article que vous avez posté. Ou bien, vous pouvez utiliser une fonction de hachage intégrée destinée à l’origine à la cryptographie (MD5, SHA1, etc.) et ne pas utiliser tous les bits.