web-dev-qa-db-fra.com

GetHashCode () sur le tableau d'octets []

Qu'est-ce que GetHashCode() calcule lorsqu'il est appelé dans le tableau byte[]? Les 2 tableaux de données au contenu égal ne fournissent pas le même hachage.

48
Chesnokov Yuriy

Comme d'autres types intégrés non primitifs, il renvoie simplement quelque chose d'arbitraire. Il n'essaye certainement pas de hacher le contenu du tableau. Voir cette réponse.

14
mquander

Les tableaux dans .NET ne remplacent pas Equals ou GetHashCode, la valeur que vous obtiendrez est donc essentiellement basée sur l’égalité des références (c'est-à-dire l'implémentation par défaut dans Object). d'un tiers). Vous voudrez peut-être implémenter IEqualityComparer<byte[]> si vous essayez d'utiliser des tableaux d'octets comme clés dans un dictionnaire, etc.

EDIT: Voici un comparateur d’égalité de tableau réutilisable qui devrait être correct tant que l’élément de tableau gère l’égalité de manière appropriée. Notez que vous ne devez pas modifier le tableau après l'avoir utilisé comme clé dans un dictionnaire, sinon vous ne pourrez pas le retrouver - même avec la même référence.

using System;
using System.Collections.Generic;

public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
    // You could make this a per-instance field with a constructor parameter
    private static readonly EqualityComparer<T> elementComparer
        = EqualityComparer<T>.Default;

    public bool Equals(T[] first, T[] second)
    {
        if (first == second)
        {
            return true;
        }
        if (first == null || second == null)
        {
            return false;
        }
        if (first.Length != second.Length)
        {
            return false;
        }
        for (int i = 0; i < first.Length; i++)
        {
            if (!elementComparer.Equals(first[i], second[i]))
            {
                return false;
            }
        }
        return true;
    }

    public int GetHashCode(T[] array)
    {
        unchecked
        {
            if (array == null)
            {
                return 0;
            }
            int hash = 17;
            foreach (T element in array)
            {
                hash = hash * 31 + elementComparer.GetHashCode(element);
            }
            return hash;
        }
    }
}

class Test
{
    static void Main()
    {
        byte[] x = { 1, 2, 3 };
        byte[] y = { 1, 2, 3 };
        byte[] z = { 4, 5, 6 };

        var comparer = new ArrayEqualityComparer<byte>();

        Console.WriteLine(comparer.GetHashCode(x));
        Console.WriteLine(comparer.GetHashCode(y));
        Console.WriteLine(comparer.GetHashCode(z));
        Console.WriteLine(comparer.Equals(x, y));
        Console.WriteLine(comparer.Equals(x, z));
    }
}
57
Jon Skeet

byte[] hérite de GetHashCode() de object, il ne la remplace pas. Donc, vous obtenez une implémentation de object.

10
rickythefox

Si ce n'est pas la même instance, il retournera des hachages différents. J'imagine que cela dépend de l'adresse mémoire où il est stocké. 

1
jishi

Solution simple

    public static int GetHashFromBytes(byte[] bytes)
    {
        return new BigInteger(bytes).GetHashCode();
    }
0
Daniil Sokolyuk