Пространство имен uuid в нескольких goroutines

Я хотел бы создать уникальный идентификатор без столкновений на языке go для масштабируемого приложения.

Википедия рекомендует вариацию UUID в пространстве имен (что я могу предположить только применительно к версии 3 или 5). Википедия конкретно заявляет:

Если для распределенных приложений требуются уникальные идентификаторы, чтобы идентификаторы UUID не конфликтовали даже при объединении данных со многих устройств, случайность начальных чисел и генераторов, используемых на каждом устройстве, должна быть надежной в течение всего срока службы приложения. Если это невозможно, RFC4122 рекомендует использовать вместо этого вариант пространства имен.

У меня есть несколько трудностей с этим

  1. Версии 3 и 5 требуют хеширования данных, что кажется ненужным по следующим причинам:

    1.1. Если приложение может использовать те же данные (для которых мне нужен другой идентификатор)

    1.2. Я предполагаю, что в терминах утечки данных внутренняя энтропия random() считается защищенной. Я не понимаю, почему криптографическое хеширование необходимо (поскольку, как я полагаю, хеширование требует НАМНОГО больше ресурсов, чем некоторые начальные вычисления).

  2. Пространство имен должно быть значением, которое защитит от коллизий, которые могут возникнуть в среде с высокой степенью параллелизма. В GO рутина может работать параллельно и может использовать тот же начальный размер из-за высокой производительности сервера (как упоминалось в Википедии). Я предполагаю, что лучшим значением для пространства имен является идентификатор программы, поэтому можно избежать коллизий на одной и той же машине. Я не могу найти какой-либо правильный способ получить уникальный идентификатор для текущего выполнения программы.

  3. Если на самом деле Википедия возвращается к версии 4 (случайной) с компонентом пространства имен, как мне создать такое руководство? документы не показывают такой вариант

TL;DR: Как правильно и безопасно генерировать уникальные идентификаторы в GOLang?

1 ответ

Решение

Документ утверждает, что: func NewRandom() - returns a Random (Version 4) UUID or panics. The strength of the UUIDs is based on the strength of the crypto/rand package.

Это означает, что этот пакет использует случайную силу криптографии / ранда для генерации UUID типа 4. Лично, если бы в реализации не было ошибок, я бы поверил в это, если бы я не генерировал миллиарды идентификаторов в день.

Другой вариант - использовать версию 5: func NewSHA1(space UUID, data []byte) UUIDи передайте ему UUID Vesion 1 в качестве пространства имен и данные из crypto/random в качестве "данных". т.е. как то так:

// this is a static namespace for this machine, say
var namespace = uuid.NewUUID()


// generate a random UUID with the global namespace
func NewNamespacedRandom() (uuid.UUID, error) {

    // read 16 crypto-random bytes
    rnd := make([]byte, 16)
    if _, err := rand.Read(rnd); err != nil {
        return nil, err
    }

    return uuid.NewSHA1(namespace, rnd), nil
}

func main() {

    u, err := NewNamespacedRandom()
    if err != nil {
        panic(err)
    }
    fmt.Println(u)

}
Другие вопросы по тегам