То, что вы хотите сделать, это попытаться распределить значения хеша как можно более равномерно по всему диапазону. Некоторые из встроенных методов хэширования довольно хороши в этом, так что вы можете попробовать что-то вроде получения хеш-кода строкового представления и просто выбросить половину битов:
ushort code = (ushort)value.ToString().GetHashCode();
Однако это также зависит от того, для чего вы собираетесь использовать хеш-код. Встроенные хэш-коды не предназначены для постоянного хранения. Алгоритмы вычисления хеш-кодов могут изменяться с любой новой версией платформы, поэтому, если вы сохраните хеш-коды в базе данных, они могут стать бесполезными в будущем. В этом случае вам вместо этого придется самостоятельно создавать алгоритм хеширования или использовать какой-либо алгоритм хеширования, предназначенный для постоянного хранения.
Один простой алгоритм, который используется для хеш-кодов для некоторых значений в платформе, состоит в том, чтобы использовать исключительные значения или сделать так, чтобы все биты значения имели значение, когда хеш-код меньше данных:
byte[] b = BitConverter.GetBytes(value);
ushort code = (ushort)(BitConverter.ToUInt16(b, 0) ^ BitConverter.ToUInt16(b, 2));
или более эффективный, но менее очевидный способ сделать то же самое:
ushort code = (ushort)((value >> 16) ^ value);
Это, конечно, не имеет запутывающих свойств для небольших значений, поэтому вы можете добавить некоторые «случайные» биты, чтобы хэш-код значительно отличался от значения:
ushort code = (ushort)(0x56D4 ^ (value >> 16) ^ value);