UUID & hashing basics in Java
UUID.randomUUID, MessageDigest for checksums.
IDs without a coordinator
A UUID is a 128-bit identifier written as 36 characters: 32 hex digits plus 4 dashes. **UUID.randomUUID() creates a version 4 UUID: 122 of its bits are random**, from a secure generator — so collisions are practically impossible.
UUID id = UUID.randomUUID();
// e.g. 3f2a9c1e-…-4…-… (36 chars)Reading a UUID
What does this print?
UUID id = UUID.fromString(
"00000000-0000-4000-8000-000000000000");
System.out.println(id.version());
System.out.println(id.toString().length());4 364 320 36
Show the answer
4 — the version is the first digit of the third group (4000). 36 — 32 hex digits plus 4 dashes.
Hashes are fingerprints
A cryptographic hash like SHA-256 turns any input into a fixed-size digest: always 32 bytes. Same input → same digest; change one letter → a totally different one. **HexFormat.of().formatHex(bytes)** (Java 17) prints it as 64 hex characters.
var md = MessageDigest.getInstance("SHA-256");
byte[] h = md.digest("hi".getBytes());
HexFormat.of().formatHex(h); // 64 charsSize of a fingerprint
What does this print?
void main() throws Exception {
var md = MessageDigest
.getInstance("SHA-256");
byte[] a = md.digest("a".getBytes());
byte[] b = md.digest("a much longer text"
.getBytes());
System.out.println(a.length);
System.out.println(b.length);
}1 1832 32256 256
Show the answer
32 both times — SHA-256 always outputs 256 bits = 32 bytes, no matter how big the input.
Storing passwords
byte[] stored = md.digest(
password.getBytes()); // SHA-256SHA-256 is so fast that attackers can try billions of guesses per second, and unsalted hashes fall to precomputed tables.
String stored = encoder.encode(password);
// bcrypt, PBKDF2 or Argon2Deliberately slow and salted, so each guess is expensive.
Which tool for which job
MD5 is broken (practical collisions): only for non-security checksums. SHA-256: integrity checks for files and downloads. **String.hashCode(): a 32-bit value for hash tables only — it collides easily. A UUID is an ID**, not a hash of anything.
Everyday uses
Database primary keys and request-tracing IDs are often UUIDs. Download pages publish SHA-256 checksums so you can verify files. And leaked databases of fast, unsalted password hashes are exactly why bcrypt and Argon2 are the industry standard.
Key takeaways
- UUID.randomUUID(): version 4, 122 random bits
- SHA-256 → 32 bytes (64 hex characters), any input size
- HexFormat.of().formatHex(bytes) prints digests (Java 17)
- Passwords need slow salted hashes (bcrypt, Argon2)
Version-4 UUIDs have 2¹²² possible values — you'd need to generate about 2.7 quintillion of them to reach a 50% chance of a single collision.
Practice questions
What does this print?
UUID id = UUID.fromString(
"123e4567-e89b-42d3-a456-556642440000");
System.out.println(id.version());
System.out.println(id.toString().length());- 4 36
- 1 32
- 4 32
- 2 36
Check your answer
4 36. The first digit of the third group (42d3) is the version: 4. The text form is 32 hex digits plus 4 dashes = 36 characters.
What does this print?
void main() throws Exception {
var md = MessageDigest.getInstance("SHA-256");
byte[] h = md.digest("hi".getBytes());
System.out.println(h.length);
String hex = HexFormat.of().formatHex(h);
System.out.println(hex.length());
}- 2 4
- 32 64
- 256 64
- 64 32
Check your answer
32 64. SHA-256 always produces 256 bits = 32 bytes, no matter the input size. Each byte is two hex characters, giving 64.