Skip to content

Instantly share code, notes, and snippets.

@PaulBradley
Last active September 5, 2024 07:24
Show Gist options
  • Save PaulBradley/08598aa755a6845f46691ab363ddf7f6 to your computer and use it in GitHub Desktop.
Save PaulBradley/08598aa755a6845f46691ab363ddf7f6 to your computer and use it in GitHub Desktop.
Generating Deterministic UUID's Within Go #golang

Generating Deterministic UUID's Within Go

I recently worked on a project which needed to interface five hospital systems to one national system. As part of the SOAP submission to the national system I needed to provide a unique UUID which would identify each user from the source hospital system. I wanted to generate the UUID on the fly as the message was being created - so I needed a way to regenerate the same UUID for the same user.

Each hospital system had their own unique user account reference. So by combining this unique account reference with an organisation identifier, I could generate a unique UUID for users with the same account reference across different facilities.

This is the function I came up with. I made use of this package to generate the UUID.

func deterministicGUID(organisation string, account string) string {
    // calculate the MD5 hash of the
    // combination of organisation
    // and account reference
    md5hash := md5.New()
    md5hash.Write([]byte(organisation + account))

    // convert the hash value to a string
    md5string := hex.EncodeToString(md5hash.Sum(nil))

    // generate the UUID from the
    // first 16 bytes of the MD5 hash
    uuid, err := uuid.FromBytes([]byte(md5string[0:16]))
    if err != nil {
        log.Fatal(err)
    }

    return uuid.String()
}

Calling the function

package main

import (
        "crypto/md5"
        "encoding/hex"
        "fmt"
        "log"
        "github.com/satori/go.uuid"
)

func main() {
      fmt.Println("UUID for user 357  @ LTH : " + deterministicGUID("LTH", "357"))
      fmt.Println("UUID for user 5689 @ BHT : " + deterministicGUID("BHT", "5689"))
}

Sample output

UUID for user 357  @ LTH : 65326566-3331-6633-3362-323139643261
UUID for user 5689 @ BHT : 61313735-6165-6434-6532-636263623834
@fieldse
Copy link

fieldse commented Jan 29, 2023

Useful!

@kmlebedev
Copy link

+1

@StephaneBunel
Copy link

StephaneBunel commented Sep 7, 2023

package main

import "github.com/google/uuid"
import "github.com/zeebo/xxh3"
import "time"

func main() {
        data := "LTH" + " " + "357"

        start := time.Now()
        guid := uuid.NewMD5(uuid.NameSpaceOID, []byte(data))
        println("md5:", time.Since(start).String(), guid.String())

        start = time.Now()
        h := xxh3.HashString128(data).Bytes()
        guid, _ = uuid.FromBytes(h[:])
        println("xxh128:", time.Since(start).String(), guid.String())
}

md5: 666ns 27b39a40-7b46-3ed5-b058-369835a583f5
xxh128: 95ns 97fa2c81-2f9e-199a-929a-3f809fa5b9d1

md5 seems evil :-)

@PaulBradley
Copy link
Author

Thanks, the xxh3 approach seems much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment