Во-первых, я хочу пояснить, что вы имеете в виду «хэш», а не «сжатие без потерь».Следует ожидать некоторых коллизий, где x1 и x2 - это одно и то же значение для разных s1 и s2.Если вы действительно имеете в виду отображение, чтобы не было столкновений, то мы должны знать намного больше о проблеме.В общем случае этого добиться невозможно (см. Принцип Pigeonhole ).Но это может быть достигнуто в некоторых особых случаях, когда на входе имеется достаточная избыточность.Или это можно сделать, поддерживая таблицу (то есть базу данных или тому подобное).Остальная часть ответа посвящена хешированию.
Если ваш UID - это UUID, созданный в iOS (или любой UUID v4), то его биты уже достаточно высокого качества, и последние четыре цифры должны быть в порядке, не делаялюбое хеширование вообще.В середине есть пара байтов, которых вы должны избегать, но весь конечный раздел является случайным и, таким образом, идеальным хешем.
Если ваш UUID не случайный, вы можете попробовать использовать хеши по умолчанию и вытянутьТребуемое количество битов из них, но некриптографические хеши не всегда имеют хорошую независимость между их битами, поэтому это может конфликтовать больше, чем вам нравится.
В этом случае используйте криптографический хеш, размер которого больше размеравам нужно и обрезать его (или взять младшие значащие биты; любой набор в порядке).Обычно это делается в криптографии.Например, SHA-512/256 - это широко используемый хеш, который вычисляет 512-битный хеш и извлекает из него 256 бит.Криптографические хэши требуют высокой независимости всех их битов, поэтому любое подмножество битов также будет устойчивым к коллизиям.
Кстати, если вы имеете в виду «4 десятичных знака», то вы должны ожидать коллизию примерно 1 раз из 100.Если вы имеете в виду 16 бит (4 шестнадцатеричных цифры), вы должны ожидать столкновения примерно один раз из 300. Это ваши лучшие сценарии и означают, что ваш хэш работает хорошо.См. Атака на день рождения для таблицы ожиданий и некоторых полезных приближений.