Last active
July 29, 2025 11:35
-
-
Save sha1n/acca3b725c6d345b98672e709717abc6 to your computer and use it in GitHub Desktop.
Type 5 UUID generator in Java & Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.UnsupportedEncodingException; | |
| import java.security.MessageDigest; | |
| import java.security.NoSuchAlgorithmException; | |
| import java.util.UUID; | |
| public class GuidV5 { | |
| public static UUID nameUUIDFrom(String name) throws UnsupportedEncodingException, NoSuchAlgorithmException { | |
| MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); | |
| sha1.update(name.getBytes("UTF-8")); | |
| byte[] data = sha1.digest(); | |
| data[6] = (byte) (data[6] & 0x0f); | |
| data[6] = (byte) (data[6] | 0x50); // set version 5 | |
| data[8] = (byte) (data[8] & 0x3f); | |
| data[8] = (byte) (data[8] | 0x80); | |
| long msb = 0L; | |
| long lsb = 0L; | |
| for (int i = 0; i <= 7; i++) | |
| msb = (msb << 8) | (data[i] & 0xff); | |
| for (int i = 8; i <= 15; i++) | |
| lsb = (lsb << 8) | (data[i] & 0xff); | |
| long mostSigBits = msb; | |
| long leastSigBits = lsb; | |
| return new UUID(mostSigBits, leastSigBits); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.security.MessageDigest | |
| import java.util.UUID | |
| object GuidV5 { | |
| def nameUUIDFrom(name: String): UUID = { | |
| val sha1 = MessageDigest.getInstance("SHA-1") | |
| sha1.update(name.getBytes("UTF-8")) | |
| val data = sha1.digest().take(16) | |
| data(6) = (data(6) & 0x0f).toByte | |
| data(6) = (data(6) | 0x50).toByte // set version 5 | |
| data(8) = (data(8) & 0x3f).toByte | |
| data(8) = (data(8) | 0x80).toByte | |
| var msb = 0L | |
| var lsb = 0L | |
| for (i <- 0 to 7) | |
| msb = (msb << 8) | (data(i) & 0xff) | |
| for (i <- 8 to 15) | |
| lsb = (lsb << 8) | (data(i) & 0xff) | |
| val mostSigBits = msb | |
| val leastSigBits = lsb | |
| new UUID(mostSigBits, leastSigBits) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.UUID | |
| import org.apache.commons.lang3.RandomUtils | |
| import org.specs2.mutable.SpecWithJUnit | |
| class GuidV5Test extends SpecWithJUnit { | |
| "nameUUIDFrom" should { | |
| "generate a type 5 uuid from the a given input" in { | |
| GuidV5.nameUUIDFrom(aString).toString.charAt(14) must beEqualTo('5') | |
| } | |
| "generate the same guid for a given input" in { | |
| val input = aString | |
| GuidV5.nameUUIDFrom(input) must beEqualTo(GuidV5.nameUUIDFrom(input)) | |
| } | |
| "be JDK UUID compliant" in { | |
| UUID.fromString(GuidV5.nameUUIDFrom(aString).toString) must not(throwA[Exception]) | |
| } | |
| } | |
| def aString = new String(RandomUtils.nextBytes(1000)) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment