C# получает уникальный хеш от всех объектов
Я хочу иметь возможность получить уникальный хеш от всех объектов. Что еще, в случае
Dictionary<string, MyObject> foo
Я хочу уникальные ключи для:
- строка
- MyObject
- Свойства в MyObject
- Foo[someKey]
- Foo
так далее..
object.GetHashCode () не гарантирует уникальные возвращаемые значения для разных объектов. Это то что мне нужно.
Любая идея? Спасибо
4 ответа
Проще говоря, это невозможно. Функция GetHashCode возвращает целое число со знаком, которое содержит 2^32 возможных уникальных значений. На 64-битной платформе вы можете иметь более 2^32 различных объектов, и, следовательно, они не могут иметь уникальные хэш-коды.
Единственный способ добиться этого - создать другую хеш-функцию, которая возвращает тип с емкостью, большей или равной количеству значений, которые могут быть созданы в работающей системе.
"Уникальный хеш", как правило, является противоречием в терминах, даже в общих чертах (и это более очевидно невозможно, если вы пытаетесь использовать Int32
как хэш-значение). Из записи в Википедии:
Хеш-функция - это любая четко определенная процедура или математическая функция, которая преобразует большой объем данных, возможно, переменного размера, в небольшой элемент данных, обычно одно целое число, которое может служить индексом для массива. Значения, возвращаемые хеш-функцией, называются хеш-значениями, хеш-кодами, хеш-суммами или просто хешами.
Обратите внимание на бит "small datum" - другими словами, будет больше возможных объектов, чем возможных значений хеша, поэтому вы не можете иметь уникальность.
Теперь это звучит так, как будто вы действительно хотите, чтобы хеш был строкой... что означает, что он не будет иметь фиксированный размер (но должен быть меньше 2 ГБ или любого другого ограничения). Простейшим способом создания этого "уникального хэша" будет сериализация объекта и преобразование результата в строку, например, используя Base64, если это двоичный формат сериализации, или просто текст, если это текстовый формат, такой как JSON. Тем не менее, это не то, что кто-то еще на самом деле признал бы как "хеширование".
Уникальный хеш-код невозможен без ограничений на ваше пространство ввода. Это потому что Object.GetHashCode
является int
, Если у вас есть больше, чем Int32.MaxValue
тогда объекты, по крайней мере, два из них должны отображаться в один и тот же хэш-код (по принципу голубя).
Определите пользовательский тип с ограниченным вводом (т. Е. Число возможных различных объектов до равенства меньше, чем Int32.MaxValue
) и тогда, и только тогда, можно создать уникальный хэш-код. Это не значит, что это будет легко, просто возможно.
Или не используйте Object.GetHashCode
механизм, но вместо этого какой-то другой способ представления хэшей, и вы можете делать то, что вы хотите. Нам нужны четкие детали того, что вы хотите, и мы используем это для того, чтобы помочь вам здесь.
Как уже говорили другие, хеш-код никогда не будет уникальным, это не главное.
Дело в том, чтобы помочь вашему Dictionary<string, MyObject> foo
чтобы найти точный экземпляр быстрее. Он будет использовать хеш-код, чтобы сузить поиск до меньшего набора объектов, а затем проверить их на равенство.
Вы можете использовать класс Guid для получения уникальных строк, если вам нужен уникальный ключ. Но это не хэш-код.