Quantum Circuit Identicons with Quarkus & Java 2D
Turn usernames into elegant, deterministic quantum avatars while learning Java 2D graphics and Quarkus REST services.
I recently stumbled over the concept of identicons again while browsing this incredible list of identicon implementations. It struck me how many different approaches exist to generate these small, unique visual identifiers. We encounter them every day without thinking about it. Google creates letter avatars when you have no profile picture. GitHub assigns you a unique blocky face when you first join. Gravatar provides deterministic icons for blogs and forums.
Identicons are everywhere. They solve a simple but important problem: give every user a recognizable avatar without needing them to upload an image. They are deterministic, privacy-friendly, and they look like they belong to you and only you.
Seeing how many implementations already exist, I thought this was the perfect excuse to explore something different. Rather than yet another pixel grid or geometric pattern, I wanted to generate identicons as quantum circuit diagrams. It is a playful idea, but it also connects two themes that matter to me: visual identity and the future of computing.
Quantum computing is one of those technologies that has been “five years away” for a long time, but things are starting to get real. Major companies like IBM, Google, and Microsoft are investing heavily. More libraries are emerging, and developers are starting to think about how classical software will interact with quantum resources. Even if you are not working on quantum algorithms today, chances are that in the next decade, hybrid applications that combine classical and quantum components will become part of mainstream software development.
This tutorial is not about building a quantum application, but about using the look and feel of quantum circuits as a fresh form of identicon. It is a chance to explore how we can turn data (a simple username) into a deterministic, elegant visual representation using Quarkus and Java 2D. It also highlights how developers can combine graphics, algorithms, and enterprise-grade Java frameworks to create something that is both practical and fun.
With that in mind, let’s build a web service that generates a “quantum signature” for every user.
Why This Matters in a Business Context
Enterprises deal with large user bases and complex systems where identity, privacy, and branding all play important roles. A system that can generate unique user visuals without storing or processing personal images solves multiple problems at once. It allows internal tools to display user avatars in a consistent way without collecting or handling sensitive image data, which helps with privacy compliance.
For companies that are working on quantum computing products or want to position themselves as innovators, using educational visuals such as quantum circuit diagrams can spark curiosity and make abstract technology feel more tangible. These identicons can double as conversation starters or subtle onboarding tools that introduce users to quantum concepts without any additional effort.
Deterministic asset generation also means there is no need for extra storage or complex asset management. The avatar is generated on the fly based on a hash, guaranteeing that the same input always results in the same output. This reduces infrastructure overhead while still providing a personalized experience.
Finally, aligning these generated visuals with a brand system, such as IBM’s design language in this tutorial (at least I tried to do that), ensures that they feel like a natural part of the company’s products. Colors, shapes, and layouts can be adapted to match corporate identity guidelines, reinforcing brand consistency across applications.
Let’s kick the tires. Enough with waiting.
Project Setup with Quarkus
Create the project using the Quarkus CLI or Maven:
mvn io.quarkus.platform:quarkus-maven-plugin:create \
-DprojectGroupId=com.ibm.developer \
-DprojectArtifactId=quantum-identicons \
-DclassName="com.ibm.developer.identicons.QuantumIdenticonResource" \
-Dextensions="rest-jackson, quarkus-awt"
cd quantum-identicons
Add one additional dependency to your pom.xml
:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
If you want to start with a ready made project, just visit my Github repository.
Modeling Quantum Circuits
Start with an enum to represent basic gates:
package com.ibm.developer.identicons;
public enum QuantumGateType {
HADAMARD, PAULI_X, PAULI_Y, PAULI_Z, CNOT, PHASE, MEASURE
}
Create a QuantumGate
class:
package com.ibm.developer.identicons;
public class QuantumGate {
public final QuantumGateType type;
public final int qubitIndex;
public final int timeStep;
public final int controlQubit; // for multi-qubit gates
public QuantumGate(QuantumGateType type, int qubitIndex, int timeStep) {
this(type, qubitIndex, timeStep, -1);
}
public QuantumGate(QuantumGateType type, int qubitIndex, int timeStep, int controlQubit) {
this.type = type;
this.qubitIndex = qubitIndex;
this.timeStep = timeStep;
this.controlQubit = controlQubit;
}
}
Define a Circuit
class:
package com.ibm.developer.identicons;
import java.util.List;
public class Circuit {
public final int qubits;
public final List<QuantumGate> gates;
public Circuit(int qubits, List<QuantumGate> gates) {
this.qubits = qubits;
this.gates = gates;
}
}
Hash-to-Circuit Logic
In HashProcessor.java
, hash the username:
package com.ibm.developer.identicons;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HashProcessor {
public static byte[] hash(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return digest.digest(input.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
In QuantumCircuitGenerator.java
:
package com.ibm.developer.identicons;
import java.util.ArrayList;
import java.util.List;
public class QuantumCircuitGenerator {
public Circuit generate(String input) {
byte[] hash = HashProcessor.hash(input);
int qubits = 2 + (hash[0] & 0x03); // 2–5
int gateCount = 3 + (hash[1] & 0x07); // 3–10
List<QuantumGate> gates = new ArrayList<>();
for (int i = 0; i < gateCount; i++) {
int b = Byte.toUnsignedInt(hash[2 + i]);
int typeIndex = b % QuantumGateType.values().length;
QuantumGateType type = QuantumGateType.values()[typeIndex];
int qubit = b % qubits;
int step = i;
if (type == QuantumGateType.CNOT) {
int control = (b + 1) % qubits;
gates.add(new QuantumGate(type, qubit, step, control));
} else {
gates.add(new QuantumGate(type, qubit, step));
}
}
return new Circuit(qubits, gates);
}
}
IBM Color Palette
package com.ibm.developer.identicons;
import java.awt.Color;
public class IBMColorPalette {
public static final Color GRAY_10 = new Color(0xf4f4f4);
public static final Color GRAY_90 = new Color(0x262626);
public static final Color BLUE_50 = new Color(0x4589ff);
public static final Color BLUE_60 = new Color(0x0f62fe);
public static final Color TEAL_50 = new Color(0x08bdba);
}
You’ll apply these colors dynamically to gates and wires.
Circuit Rendering with Java 2D
In CircuitRenderer.java
:
package com.ibm.developer.identicons;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
public class CircuitRenderer {
public BufferedImage render(Circuit circuit) {
int width = 400;
int height = 100 + circuit.qubits * 40;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(IBMColorPalette.GRAY_10);
g.fillRect(0, 0, width, height);
// Draw qubit wires
for (int i = 0; i < circuit.qubits; i++) {
int y = 50 + i * 40;
g.setColor(IBMColorPalette.BLUE_60);
g.drawLine(20, y, width - 20, y);
}
// Draw gates
for (QuantumGate gate : circuit.gates) {
int x = 40 + gate.timeStep * 40;
int y = 50 + gate.qubitIndex * 40;
switch (gate.type) {
case HADAMARD -> drawGate(g, x, y, "H", IBMColorPalette.BLUE_50);
case PAULI_X -> drawGate(g, x, y, "X", IBMColorPalette.TEAL_50);
case CNOT -> drawCNOT(g, x, y, 50 + gate.controlQubit * 40);
default -> drawGate(g, x, y, gate.type.name().substring(0, 1), IBMColorPalette.BLUE_50);
}
}
g.dispose();
return image;
}
private void drawGate(Graphics2D g, int x, int y, String label, Color color) {
g.setColor(color);
g.fillRect(x - 10, y - 10, 20, 20);
g.setColor(IBMColorPalette.GRAY_90);
g.drawString(label, x - 4, y + 5);
}
private void drawCNOT(Graphics2D g, int targetX, int targetY, int controlY) {
g.setColor(IBMColorPalette.TEAL_50);
g.drawLine(targetX, controlY, targetX, targetY);
g.fillOval(targetX - 4, controlY - 4, 8, 8);
g.drawOval(targetX - 10, targetY - 10, 20, 20);
g.drawLine(targetX, targetY - 8, targetX, targetY + 8);
g.drawLine(targetX - 8, targetY, targetX + 8, targetY);
}
}
REST API for Image Generation
In QuantumIdenticonResource.java
:
package com.ibm.developer.identicons;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@Path("/api/identicons")
public class QuantumIdenticonResource {
QuantumCircuitGenerator generator = new QuantumCircuitGenerator();
CircuitRenderer renderer = new CircuitRenderer();
@GET
@Path("/{username}")
@Produces("image/png")
public Response generateIdenticon(@PathParam("username") String username) throws IOException {
Circuit circuit = generator.generate(username);
BufferedImage image = renderer.render(circuit);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
return Response.ok(baos.toByteArray()).build();
}
@GET
@Path("/{username}/preview")
@Produces(MediaType.APPLICATION_JSON)
public Circuit getCircuitInfo(@PathParam("username") String username) {
return generator.generate(username);
}
}
Run and Explore
Start Quarkus in dev mode:
./mvnw quarkus:dev
Access:
PNG image: http://localhost:8080/api/identicons/your@email.com
JSON preview:
/api/identicons/your@email.com/preview
What’s Next?
Add SVG output
Animate circuits using frame sequences
Cache images using
Caffeine
Batch generate identicons from CSV lists
Expose dark/light theme toggles via query params
Further Reading
Let your users carry their own quantum signature—pixel-perfect and deterministically mysterious.
Ready to merge art, code, and quantum thinking? Fork it. Extend it. And don’t forget: every user has a wavefunction worth visualizing.