From 560e9adf198dee5f5206ecdb024bf61be88d35ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Tr=C3=A9guier?= Date: Sun, 15 Sep 2024 19:30:22 +0200 Subject: [PATCH] Make user tint more random --- .../java/app/fyreplace/api/data/User.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/app/fyreplace/api/data/User.java b/src/main/java/app/fyreplace/api/data/User.java index 07ec1f4..22dde63 100644 --- a/src/main/java/app/fyreplace/api/data/User.java +++ b/src/main/java/app/fyreplace/api/data/User.java @@ -15,6 +15,7 @@ import jakarta.ws.rs.NotAuthorizedException; import jakarta.ws.rs.core.SecurityContext; import java.awt.Color; +import java.security.MessageDigest; import java.time.Duration; import java.time.Instant; import java.util.Arrays; @@ -22,7 +23,7 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -import java.util.zip.CRC32; +import lombok.SneakyThrows; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; @@ -154,11 +155,12 @@ public boolean getBlocked() { return Block.count("source = ?1 and target = ?2", currentUser, this) > 0; } + @SneakyThrows @Schema(required = true, pattern = "^#[A-F0-9]{6}$") public String getTint() { - final var crc = new CRC32(); - crc.update(username.getBytes()); - final var hue = (float) (crc.getValue() / Math.pow(2, 32)); + final var md5 = MessageDigest.getInstance("MD5"); + final var digest = md5.digest(username.getBytes()); + final var hue = bytesToFloat(digest); final var h = hue * 6; final var variance = (h - (float) Math.floor(h)) * 0.25f; final var brightness = (int) h % 2 == 0 ? 1f - variance : 0.75f + variance; @@ -261,6 +263,17 @@ public static User getFromSecurityContext(final SecurityContext context, @Nullab return user; } + private static float bytesToFloat(byte[] bytes) { + final var bytesToUse = Math.min(bytes.length, Long.BYTES); + var result = 0L; + + for (var i = 0; i < bytesToUse; i++) { + result = (result << Byte.SIZE) | (bytes[i] & 0xFF); + } + + return (float)Math.abs((double)result / Long.MAX_VALUE); + } + public enum Rank { CITIZEN, MODERATOR,