Skip to content

Instantly share code, notes, and snippets.

@andy722
Created September 24, 2021 10:38
Show Gist options
  • Save andy722/46bc7f1d8caa2c6e9b4cd74f3a5e0dfa to your computer and use it in GitHub Desktop.
Save andy722/46bc7f1d8caa2c6e9b4cd74f3a5e0dfa to your computer and use it in GitHub Desktop.
UUIDv4 with custom payload
import com.google.common.base.Preconditions
import java.nio.ByteBuffer
import static com.google.common.base.Preconditions.checkState
// See java.util.UUID#randomUUID
UUID generateV4(byte[] src) {
checkState src.length <= 14
// Enrich initial payload w/ version and variant for a proper UUID type
final byte[] dst = new byte[16].tap { dst ->
final copy = { int iDst, int iSrc ->
// Debug
// println "dst[$iDst] = src[$iSrc]"
dst[iDst] = iSrc < src.length ? src[iSrc] : (byte) 0
}
int iSrc = 0, iDst = 0
// Bytes 0..5
for (; iDst < 6; iSrc++, iDst++) copy iDst, iSrc
// Byte 6
dst[6] &= 0x0f /* clear version */
dst[6] |= 0x40 /* set to version 4 */
iDst++
// Byte 7
copy iDst++, iSrc++
// Byte 8
dst[8] &= 0x3f /* clear variant */
dst[8] |= 0x80 /* set to IETF variant */
iDst++
// Byte 9..15
for (; iDst < 16; iSrc++, iDst++) copy iDst, iSrc
}
new UUID(dst)
}
// Read initial payload skipping version and variant
byte getPayload(UUID uuid) {
final src = ByteBuffer.wrap(new byte[16])
.tap {
putLong(uuid.mostSignificantBits)
putLong(uuid.leastSignificantBits)
}
.array()
// Read initial payload skipping version and variant
return new byte[14].tap { dst ->
final copy = { int iDst, int iSrc ->
// Debug
// println "dst[$iDst] = src[$iSrc]"
dst[iDst] = iSrc < src.length ? src[iSrc] : (byte) 0
}
int iSrc = 0, iDst = 0
// Bytes 0..5
for (; iDst < 6; iSrc++, iDst++) copy iDst, iSrc
// Byte 6: version
iSrc++
// Byte 7
copy iDst++, iSrc++
// Byte 8: variant
iSrc++
// Byte 9..15
for (; iSrc < 16; iSrc++, iDst++) copy iDst, iSrc
}
}
//
// Specific usage
//
UUID getWaybillEventId(Long waybillId, int eventType) {
final buf = ByteBuffer.allocate(14).tap {
putLong waybillId // 8
putInt eventType // 4
}
generateV4 buf.array()
}
Tuple2<Long, Integer> parseWaybillEventId(UUID uuid) {
final dst = getPayload uuid
ByteBuffer.wrap(dst).with {
Tuple.tuple(
it.long,
it.int
)
}
}
long waybillId = 999999999999999999L
int eventType = 1I
final uuid = getWaybillEventId(waybillId, eventType)
println "waybillId: $waybillId, eventType:$eventType -> $uuid (version: ${uuid.version()}, variant: ${uuid.variant()})"
assert uuid.version() == 4
final parsed = parseWaybillEventId(uuid)
println "uuid $uuid -> waybillId: $parsed.v1, eventType:$parsed.v2"
assert parsed.v1 == waybillId
assert parsed.v2 == eventType
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment