JAL-4435 Changes to ColorUtils and StringUtils (MD5 is a bit rubbish)
authorBen Soares <b.soares@dundee.ac.uk>
Mon, 11 Nov 2024 20:35:49 +0000 (20:35 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Mon, 11 Nov 2024 20:35:49 +0000 (20:35 +0000)
src/jalview/util/ColorUtils.java
src/jalview/util/StringUtils.java

index 73ad0ef..d98ba6c 100644 (file)
@@ -420,8 +420,8 @@ public class ColorUtils
 
   public enum ColourScheme
   {
-    AVOID_RED, AVOID_GREEN, AVOID_BLUE, SATURATED, DESATURATED, GREYISH,
-    GREYSCALE, BRIGHT, MEDIUM, DARK
+    NONE, AVOID_RED, AVOID_GREEN, AVOID_BLUE, SATURATED, DESATURATED,
+    GREYISH, GREYSCALE, BRIGHT, MEDIUM, DARK
   }
 
   public static float[] getHSBRanges(String colourScheme)
@@ -432,61 +432,64 @@ public class ColorUtils
     float Smax = 1.0f;
     float Bmin = 0.6f;
     float Bmax = 1.0f;
-    for (String scheme : colourScheme.split(","))
+    if (!colourScheme.contains(ColourScheme.NONE.name()))
     {
-      Console.debug("Applying colourScheme component " + scheme);
-      ColourScheme cs;
-      try
-      {
-        cs = ColourScheme.valueOf(scheme);
-      } catch (IllegalArgumentException | NullPointerException e)
+      for (String scheme : colourScheme.split(","))
       {
-        Console.warn("Did not recognise something in the colour scheme '"
-                + colourScheme + "'");
-        return new float[] { Hmin, Hmax, Smin, Smax, Bmin, Bmax };
-      }
-      switch (cs)
-      {
-      case AVOID_RED:
-        Hmin = 0.15f;
-        Hmax = 0.85f;
-        break;
-      case AVOID_GREEN:
-        Hmin = 0.48f;
-        Hmax = 0.18f;
-        break;
-      case AVOID_BLUE:
-        Hmin = 0.81f;
-        Hmax = 0.51f;
-        break;
-      case SATURATED:
-        Smin = 1.0f;
-        Smax = 1.0f;
-        break;
-      case DESATURATED:
-        Smin = 0.2f;
-        Smax = 0.6f;
-        break;
-      case GREYISH:
-        Smin = 0.0f;
-        Smax = 0.2f;
-      case GREYSCALE:
-        Smin = 0.0f;
-        Smax = 0.0f;
-        Bmin = 0.1f;
-        Bmax = 0.9f;
-        break;
-      case BRIGHT:
-        Bmin = 1.0f;
-        Bmax = 1.0f;
-        break;
-      case MEDIUM:
-        Bmin = 0.6f;
-        Bmax = 0.8f;
-      case DARK:
-        Bmin = 0.1f;
-        Bmax = 0.4f;
-        break;
+        Console.debug("Applying colourScheme component " + scheme);
+        ColourScheme cs;
+        try
+        {
+          cs = ColourScheme.valueOf(scheme);
+        } catch (IllegalArgumentException | NullPointerException e)
+        {
+          Console.warn("Did not recognise something in the colour scheme '"
+                  + colourScheme + "'");
+          return new float[] { Hmin, Hmax, Smin, Smax, Bmin, Bmax };
+        }
+        switch (cs)
+        {
+        case AVOID_RED:
+          Hmin = 0.15f;
+          Hmax = 0.85f;
+          break;
+        case AVOID_GREEN:
+          Hmin = 0.48f;
+          Hmax = 0.18f;
+          break;
+        case AVOID_BLUE:
+          Hmin = 0.81f;
+          Hmax = 0.51f;
+          break;
+        case SATURATED:
+          Smin = 1.0f;
+          Smax = 1.0f;
+          break;
+        case DESATURATED:
+          Smin = 0.2f;
+          Smax = 0.6f;
+          break;
+        case GREYISH:
+          Smin = 0.0f;
+          Smax = 0.2f;
+        case GREYSCALE:
+          Smin = 0.0f;
+          Smax = 0.0f;
+          Bmin = 0.1f;
+          Bmax = 0.9f;
+          break;
+        case BRIGHT:
+          Bmin = 1.0f;
+          Bmax = 1.0f;
+          break;
+        case MEDIUM:
+          Bmin = 0.6f;
+          Bmax = 0.8f;
+        case DARK:
+          Bmin = 0.1f;
+          Bmax = 0.4f;
+          break;
+        }
       }
     }
     return new float[] { Hmin, Hmax, Smin, Smax, Bmin, Bmax };
@@ -560,7 +563,7 @@ public class ColorUtils
 
     // use first three bytes from MD5 rather than String.hashCode() as short
     // strings all low number hashCodes
-    byte[] hash = StringUtils.getMD5Bytes(name);
+    byte[] hash = StringUtils.getHashedBytes(name);
     int b = hash.length > 0 ? Byte.toUnsignedInt(hash[0]) : 0;
     int g = hash.length > 1 ? Byte.toUnsignedInt(hash[1]) : 0;
     int r = hash.length > 2 ? Byte.toUnsignedInt(hash[2]) : 0;
index 3b3cb47..54a63ce 100644 (file)
@@ -650,26 +650,34 @@ public class StringUtils
     return max;
   }
 
+  private final static String fixedSalt = "Fixed Jalview Salt String";
+
   /*
    * return an MD5 hash of the given String
    */
-  public static byte[] getMD5Bytes(String name)
+  public static byte[] getHashedBytes(String name)
   {
-    final String alg = "MD5";
+    final String alg = "SHA-256";
+    final String enc = "UTF-8";
     try
     {
-      MessageDigest md5 = MessageDigest.getInstance(alg);
-      return md5.digest(name.getBytes());
+      MessageDigest hash = MessageDigest.getInstance(alg);
+      Console.debug("Using hashing algorithm " + alg);
+      return hash.digest((name + fixedSalt).getBytes(enc));
     } catch (NoSuchAlgorithmException e)
     {
       Console.warn("Could not find hashing algorithm '" + alg + "'");
-      return null;
+    } catch (UnsupportedEncodingException e)
+    {
+      Console.warn("Could not find character encoding '" + enc + "'");
     }
+    return null;
   }
 
-  public static String getMD5String(String name)
+  public static String getHashedString(String name)
   {
-    byte[] hashBytes = getMD5Bytes(name);
+    // add a string to ensure some length to the name string
+    byte[] hashBytes = getHashedBytes(name);
     if (hashBytes == null)
     {
       return null;