Как мне сгенерировать подходящее и вместе с тем уникальное значение, которое может сосуществовать с глобальными уникальными идентификаторами?
Клиенту понадобилось сгенерировать глобальный уникальный идентификатор (GUID) для каждого экземпляра устройства, которые попадают к ним:
Серийный номер каждого устройства составляет 20 бит (четыре с половиной байта). Нам нужно сгенерировать значения GUID для каждого устройства такие, что когда устройство будет подключено повторно, мы должны сгенерировать для него тот же самый GUID, что ни для одной пары устройств не будет генерироваться двух одинаковых GUID и что получаемые значения не будут пересекаться с другими GUID, сгенерированными для каких-либо иных целей. Один из наших инженеров предложил просто запускать утилиту uuidgen и вместо последних девяти шестнадцатеричных разрядов подставлять серийный номер. Является ли такая техника пригодной для поставленной задачи?
Эта ситуация очень похожа на ловушку, в которую люди попадают, считая что половина GUID настолько же уникальна, как и целый идентификатор. Запомните, что эта уникальность достигается только взаимосвязью всех частей GUID. Если вы просто возьмете и отбросите часть идентификатора, то весь алгоритм развалится.
Однако в данном случае вам повезло. Классический GUID первого типа использует 60 бит для кодирования отметки времени (timestamp) и еще 48 — для идентификации местоположения (компьютера). Вы можете взять сетевую карту, получить ее MAC-адрес, а затем разбить ее вдребезги молотком. Теперь у вас есть уникальное местоположение. Поместите ваши двадцать бит уникальных данных в качестве отметки времени, и вы получите GUID первого типа, который гарантированно не пересечется с другим GUID.
Но если у вас более 60 бит уникальных данных, этот трюк не пройдет. К счастью, в RFC4122 объясняется, как создать так называемые UUID, основанные на наименовании. Эти UUID можно сгенерировать повторно из тех же самых данных и гарантированно получить одинаковый результат. В разделе 4.3 объясняется, как это сделать. Результатом будет UUID третьего или пятого типа, в зависимости от того, какой алгоритм вы выберете.