About UUID Converter
A UUID is 128 bits. Everything else - the 36-character hyphenated string, 32 hex characters, 22 characters of Base64, a pair of signed 64-bit integers, 16 raw bytes - is a representation of those same bits, and converting between them is lossless. What is not lossless, and what causes almost every bug in this area, is getting the byte order wrong on the way.
The canonical string form is deceptive because it is not a plain sequence of bytes. RFC 4122 defines the first three groups as integer fields - a 32-bit time_low, a 16-bit time_mid, a 16-bit time_hi_and_version - and the last two as a byte sequence. Any platform that serialises those first three fields in its native little-endian order produces bytes in a different order from the string. That is exactly what Microsoft's GUID does, and it is why the same UUID moving between a .NET service and a Java one can arrive byte-reversed in its first half.
Java has its own version of the problem. UUID exposes the value as two signed longs, getMostSignificantBits and getLeastSignificantBits, and because Java has no unsigned types those longs are frequently negative. Printing them as unsigned, or storing them in a database column that expects unsigned, silently changes the value.
The compact encodings are worth knowing for URLs and storage. The 128 bits Base64-encode to 22 characters without padding - use Base64URL so the result needs no percent-encoding - and Base58 also gives 22 characters while avoiding visually ambiguous glyphs. Both are considerably shorter than 36 characters and fully reversible.
This tool shows every representation of the same value at once, including the byte-swapped variants, so you can identify which convention produced the data you are holding. Conversion is pure arithmetic in your browser and nothing is transmitted.
How to use the UUID Converter
- Paste a UUID in any form - canonical, unhyphenated hex, Base64, or a $binary value from MongoDB.
- Read across the representations: hex, Base64, Base64URL, integer pair, byte array.
- Compare the standard and byte-swapped forms if the value came from .NET, a Java driver, or a binary database column.
- Copy the representation the receiving system expects, and confirm the byte count is 16 rather than 32 characters mistaken for 32 bytes.
Examples
-
UUID (RFC 4122)
550e8400-e29b-41d4-a716-446655440000 -
URN
urn:uuid:550e8400-e29b-41d4-a716-446655440000 -
Braced GUID
{550e8400-e29b-41d4-a716-446655440000} -
32-char hex
550e8400e29b41d4a716446655440000 -
Base64 (standard MIME)
VQ6EAOKbQdSnFkRmVUQAAA== -
Base64 (URL-safe)
VQ6EAOKbQdSnFkRmVUQAAA -
Uint128 (decimal)
113059749145936325402354257176981405696 -
JSON byte array
[85,14,132,0,226,155,65,212,167,22,68,102,85,68,0,0] -
MongoDB $binary (subtype 04)
{ "$binary": { "base64": "VQ6EAOKbQdSnFkRmVUQAAA==", "subType": "04" } }
UUID Converter in code
The same operation this tool performs, in the languages you are most likely to need it.
const hex = (u) => u.replace(/-/g, "");
const bytes = (u) => Uint8Array.from(hex(u).match(/../g).map((h) => parseInt(h, 16)));
// 22-character Base64URL - safe in a URL with no escaping
const toB64Url = (u) =>
btoa(String.fromCharCode(...bytes(u)))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const fromB64Url = (s) => {
const b64 = s.replace(/-/g, "+").replace(/_/g, "/");
const b = Uint8Array.from(atob(b64.padEnd(b64.length + ((4 - b64.length % 4) % 4), "=")),
(c) => c.charCodeAt(0));
const h = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
return `${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20)}`;
};
// As a single 128-bit integer
const toBigInt = (u) => BigInt("0x" + hex(u));
var g = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");
// ToByteArray() writes the FIRST THREE FIELDS LITTLE-ENDIAN.
// This does not match the string, and does not match Java or Python.
byte[] native = g.ToByteArray();
// 00 84 0e 55 | 9b e2 | d4 41 | a7 16 44 66 55 44 00 00
// ^ reversed ^ rev ^ rev
// .NET 8+ gives you the RFC 4122 order explicitly:
byte[] rfc = g.ToByteArray(bigEndian: true);
// 55 0e 84 00 | e2 9b | 41 d4 | a7 16 44 66 55 44 00 00
// Before .NET 8, swap by hand:
static byte[] ToRfc4122(Guid g) {
var b = g.ToByteArray();
Array.Reverse(b, 0, 4);
Array.Reverse(b, 4, 2);
Array.Reverse(b, 6, 2);
return b;
}
import java.util.UUID;
import java.nio.ByteBuffer;
UUID u = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
// These are SIGNED longs and are very often negative.
long hi = u.getMostSignificantBits(); // 6129484611666145236
long lo = u.getLeastSignificantBits(); // -6427060979900814848 <- negative
// Correct 16 bytes, RFC 4122 order
byte[] rfc = ByteBuffer.allocate(16).putLong(hi).putLong(lo).array();
// Back again
ByteBuffer bb = ByteBuffer.wrap(rfc);
UUID back = new UUID(bb.getLong(), bb.getLong());
// Printing lo as if unsigned gives a different number - use
// Long.toUnsignedString(lo) only for display, never as a value.
import uuid, base64
u = uuid.UUID("550e8400-e29b-41d4-a716-446655440000")
u.hex # '550e8400e29b41d4a716446655440000'
u.bytes # RFC 4122 order
u.bytes_le # .NET / GUID order - first 3 fields little-endian
u.int # 113059749145936325402354257176981405696
u.fields # the six structural fields
# 22-character Base64URL
short = base64.urlsafe_b64encode(u.bytes).rstrip(b"=").decode()
back = uuid.UUID(bytes=base64.urlsafe_b64decode(short + "=="))
# bytes vs bytes_le is THE conversion to get right when moving
# UUIDs between .NET and everything else.
-- PostgreSQL: native 16-byte uuid type, no conversion needed
SELECT '550e8400-e29b-41d4-a716-446655440000'::uuid;
SELECT id::text FROM things; -- back to canonical string
-- MySQL 8+: BINARY(16) with helper functions
SELECT UUID_TO_BIN('550e8400-e29b-41d4-a716-446655440000'); -- as-is
SELECT UUID_TO_BIN('550e8400-e29b-41d4-a716-446655440000', 1); -- time-swapped
SELECT BIN_TO_UUID(id, 1) FROM things; -- the flag MUST match how it was written
-- SQL Server: uniqueidentifier sorts by the LAST bytes first, which is
-- why NEWID() ordering looks arbitrary even for sequential values.
SELECT CAST('550e8400-e29b-41d4-a716-446655440000' AS uniqueidentifier);
When you need this
- Shortening a UUID to 22 characters for a URL without losing any information.
- Working out whether a binary column holds RFC 4122 bytes or .NET GUID bytes.
- Converting a Java UUID's two signed longs into a canonical string.
- Decoding a MongoDB $binary value into a readable UUID.
- Producing the exact byte array a driver or fixture expects.
Common problems and what causes them
- The .NET GUID byte order
- Guid.ToByteArray() serialises the first three fields little-endian, so its bytes do not match the string form or any other platform. Use ToByteArray(bigEndian: true) on .NET 8+, or reverse the first 4, next 2 and next 2 bytes by hand. This is the single most common cross-platform UUID bug.
- Java's signed longs printed as unsigned
- getLeastSignificantBits often returns a negative number because Java has no unsigned types. Long.toUnsignedString is fine for display but is a different number - never round-trip through it or store it as an unsigned value.
- MySQL's UUID_TO_BIN swap flag mismatched
- UUID_TO_BIN(u, 1) rearranges the time fields for better index locality, and BIN_TO_UUID must be called with the same flag. Writing with the flag and reading without it returns a different UUID with no error.
- 32 hex characters mistaken for 32 bytes
- A UUID is 16 bytes and 32 hex characters. Treating the hex text as bytes gives a 32-byte value, which is how UUIDs end up in oversized columns and why key-length checks fail.
- Base64 with padding in a URL
- Standard Base64 of 16 bytes is 24 characters including two = signs, and both = and the + and / characters need escaping in a URL. Use Base64URL and strip the padding to get a clean 22 characters.
- SQL Server's unusual sort order
- uniqueidentifier compares the last six bytes first, then works backwards. Sequential GUIDs therefore do not sort in creation order, and NEWSEQUENTIALID() is designed around this rather than around the string form.
FAQ
- Is converting a UUID between representations lossless?
- Yes - all of them encode the same 128 bits. What is not preserved automatically is byte order: the .NET GUID layout and the RFC 4122 layout differ in the first three fields, so a conversion that ignores that produces a different UUID.
- How do I shorten a UUID for a URL?
- Base64URL-encode the 16 bytes and drop the padding: 22 characters, fully reversible, no escaping needed. Base58 also gives 22 characters and avoids ambiguous glyphs. Do not truncate - dropping bits raises collision probability sharply.
- Why do .NET and Java produce different bytes for the same UUID?
- Because Guid.ToByteArray() writes the first three fields in little-endian order, matching the Windows GUID memory layout, while Java and Python use RFC 4122 order. Same value, different byte sequence. Use ToByteArray(bigEndian: true) or reverse the first 4, 2 and 2 bytes.
- Why is my Java UUID's long negative?
- Java longs are signed and a UUID's 64-bit halves regularly exceed Long.MAX_VALUE. The bits are correct; only the decimal rendering looks wrong. Keep them as longs, and use Long.toUnsignedString purely for display.
- How should I store a UUID in a database?
- PostgreSQL: the native uuid type. MySQL: BINARY(16) via UUID_TO_BIN, using the swap flag consistently. SQL Server: uniqueidentifier. Avoid CHAR(36) - it is more than twice the size in the row and in every index.
- What is the integer form of a UUID?
- The 128 bits read as one unsigned integer, which is why languages without a 128-bit type expose it as two 64-bit halves instead. It is a valid lossless representation, though it is rarely the most convenient one.
- Does byte order change the UUID string?
- MongoDB and some databases store UUIDs with a different endian layout in BSON. This tool shows standard RFC string forms from the parsed bytes; use the MongoDB tool if you need Extended JSON $binary.
- Is my data uploaded?
- No. Conversion happens entirely in your browser tab.
- What formats are supported?
- Plain UUID, URN, braces/parentheses, hex, standard and URL-safe Base64, uint128 decimal, JSON byte arrays, and MongoDB Extended JSON.