Comment générer un code de hachage unique pour un objet, basé sur son contenu?
J'ai besoin de générer un unique code de hachage pour un objet, en fonction de son contenu, par exemple de type DateTime(2011,06,04) devrait être égal à DateTime(2011,06,04).
- Je ne peux pas utiliser .GetHashCode() car elle est susceptible de générer le même code de hachage pour les objets avec des contenus différents.
- Je ne peux pas utiliser .GetID de ObjectIDGenerator car il génère un autre code de hachage pour les objets avec le même contenu.
- Si l'objet contient d'autres sous-objets, il doit vérifier de manière récursive.
- Il faut travailler sur les collections.
La raison que j'ai besoin d'écrire cela? Je suis en train d'écrire une couche de mise en cache à l'aide de PostSharp.
Mise à jour
Je crois que j'ai posé la mauvaise question. Comme Jon Skeet a souligné, pour être sur le côté sûr, j'ai besoin d'autant de combinaisons uniques dans la clé de cache comme il y a des combinaisons de données dans l'objet. Donc, la meilleure solution pourrait être de construire une longue chaîne qui code pour le public propriétés de l'objet, à l'aide de la réflexion. Les objets ne sont pas trop gros donc c'est très rapide et efficace:
- Efficace pour construire la clé de cache (il suffit de convertir le public propriétés de l'objet en une chaîne de caractères).
- Son efficacité à vérifier pour un accès au cache (comparer deux chaînes de caractères).
source d'informationauteur Contango
Vous devez vous connecter pour publier un commentaire.
Si vous avez besoin de créer un unique code de hachage, alors vous avez l'impression de parler d'un nombre qui peut représenter autant d'états que votre type peut avoir. Pour
DateTime
que c'est prendre les Tiques de la valeur et de laDateTimeKind
je crois.Vous pourriez être en mesure de s'en tirer en supposant que les deux premiers bits de la
Ticks
propriété vont être de zéro, et les utiliser pour stocker le genre. Cela signifie que vous êtes très bien jusqu'à l'année 7307 aussi loin que je peux dire:À partir d'un commentaire:
Qui semble comme une exigence inhabituelle mais puisque c'est votre exigence, nous allons faire le calcul.
Supposons que vous faites un milliard d'objets uniques d'un an-trente par seconde 10 trillions de trillions de trillions d'années. 1049 objets uniques que vous êtes en train de créer. Travailler le calcul est assez facile; la probabilité d'au moins un hash collision dans le temps, qui est au-dessus de l'un dans 1018 lorsque la taille en bits de la table de hachage est de moins de 384.
Par conséquent, vous aurez besoin d'au moins un de 384 bits de code de hachage d'avoir le niveau de l'unicité de ce que vous avez besoin. C'est une pratique de la taille, de 12 int32s. Si vous allez faire de plus de 30 objets une seconde ou souhaitez la probabilité d'être inférieur à 1018 alors plus de bits sera nécessaire.
Pourquoi avez-vous de telles exigences strictes?
Voici ce que je ferais si j'avais à vos exigences énoncées. Le premier problème est de convertir tous les possibles donnée dans une auto-description de la séquence de bits. Si vous avez un format de sérialisation déjà, utilisez-le. Si non, en inventer un qui peut sérialiser tous les objets qui vous intéressent dans le hachage.
Puis, à hachage de l'objet, de le sérialiser dans un tableau d'octets, puis exécutez le tableau d'octets à travers le SHA-384 ou SHA-512 algorithme de hachage. Qui produira un professionnel-crypto-grade 384 ou 512 bits de hachage qui est censé être unique, même face à des attaquants d'essayer de forcer les collisions. Que le nombre de bits devrait être plus que suffisant pour assurer une faible probabilité de collision dans votre dix trillions de trillions de trillions de ans.
On ne parle pas d'un code de hachage ici, vous avez besoin d'un numéro de la représentation de votre état, pour que ce soit unique, il peut être incroyablement élevé en fonction de votre structure de l'objet.
Pourquoi vous n'utilisez pas régulièrement hashcode au lieu de cela, et de gérer les collisions en comparant les objets? Qui semble être le plus raisonnable.
C'est tout à fait normal pour un code de hachage d'avoir des collisions. Si votre code de hachage a une longueur fixe (32 bits dans le cas de la norme .NET code de hachage), alors vous êtes lié pour avoir collisions avec les valeurs dont la portée est plus grande que (par exemple, à 64 bits pour de long; n*64 bits pour un tableau de n aspire etc).
En fait pour n'importe quel code de hachage avec une longueur finie N, il y aura toujours des collisions pour les collections de plus de N éléments.
Ce que vous demandez n'est pas possible dans le cas général.
Une plus BrokenGlass réponse, qui j'ai voté et considérez la bonne:
À l'aide de la
GetHashCode
/Equals
méthode signifie que si deux objets de hachage à la même valeur que vous 'll être en s'appuyant dans leurEquals
mise en œuvre afin de vous dire s'ils sont équivalents.À moins que ces objets remplacer
Equals
(ce qui, concrètement, signifie qu'ils mettent en œuvreIEquatable<T>
oùT
est leur type), le défaut de mise en œuvre deEquals
va faire une référence de comparaison. Cela signifie que votre cache aurait tort de rendement d'une miss pour les objets qui sont "égaux" dans le sens des affaires, mais ont été construits de façon indépendante.Envisager l'utilisation de modèle de votre cache soigneusementparce que si vous vous retrouvez à l'utiliser pour les classes qui ne sont pas
IEquatable
et d'une manière où vous vous attendez à la vérification de la non-référence à l'égalité des objets pour l'égalité, le cache sera complètement inutile.Nous avons eu exactement la même exigence et voici la fonction que j'ai trouvé. C'est ce qui fonctionne bien pour les types d'objets que nous avons besoin de cache
Ainsi par exemple, si nous avons quelque chose comme ce
Cache de clé généré par la méthode ci-dessus seront
Vous pouvez calculer ex somme md5 (ou quelque chose comme ça) de l'objet sérialisé en json.
Si vous ne souhaitez que certaines propriétés de la matière, vous pouvez créer des objet anonyme sur le chemin:
- Je l'utiliser pour vérifier si quelqu'un raté avec ma base de données stockant de licence de base de données. Vous pouvez également ajouter json variable avec quelques graines pour compliquer les choses
Cette méthode d'extension en fonction de vos besoins? Si l'objet est un type de valeur, elle retourne à son code de hachage. Sinon, il récursivement obtient la valeur de chaque propriété et les combine en un seul hachage.