Conversion.hexTo*() methods now throw IllegalArgumentException instead
of StringIndexOutOfBoundsException

Better exception messages
diff --git a/src/main/java/org/apache/commons/lang3/Conversion.java b/src/main/java/org/apache/commons/lang3/Conversion.java
index 31d9ada..8883907 100644
--- a/src/main/java/org/apache/commons/lang3/Conversion.java
+++ b/src/main/java/org/apache/commons/lang3/Conversion.java
@@ -776,25 +776,25 @@ public static int hexDigitToInt(final char hexDigit) {
     }
 
     /**
-     * Converts a hexadecimal string into a byte using the default (little-endian, Lsb0) byte and
-     * bit ordering.
+     * Converts a hexadecimal string into a byte using the default (little-endian, Lsb0) byte and bit ordering.
      *
-     * @param src the hexadecimal string to convert
-     * @param srcPos the position in {@code src}, in Char unit, from where to start the
-     *            conversion
-     * @param dstInit initial value of the destination byte
-     * @param dstPos the position of the LSB, in bits, in the result byte
-     * @param nHex the number of Chars to convert
-     * @return a byte containing the selected bits
-     * @throws IllegalArgumentException if {@code (nHex-1)*4+dstPos >= 8}
+     * @param src     the hexadecimal string to convert.
+     * @param srcPos  the position in {@code src}, in char unit, from where to start the conversion.
+     * @param dstInit initial value of the destination byte.
+     * @param dstPos  the position of the LSB, in bits, in the result byte.
+     * @param nHex    the number of Chars to convert.
+     * @return a byte containing the selected bits.
+     * @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 8}.
      */
-    public static byte hexToByte(final String src, final int srcPos, final byte dstInit, final int dstPos,
-            final int nHex) {
+    public static byte hexToByte(final String src, final int srcPos, final byte dstInit, final int dstPos, final int nHex) {
         if (0 == nHex) {
             return dstInit;
         }
         if ((nHex - 1) * 4 + dstPos >= 8) {
-            throw new IllegalArgumentException("(nHex-1)*4+dstPos is greater than or equal to 8");
+            throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater than or equal to 8");
+        }
+        if (srcPos + nHex > src.length()) {
+            throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d  > src.length()", srcPos, nHex, src.length()));
         }
         byte out = dstInit;
         for (int i = 0; i < nHex; i++) {
@@ -811,20 +811,23 @@ public static byte hexToByte(final String src, final int srcPos, final byte dstI
      * ordering.
      *
      * @param src the hexadecimal string to convert
-     * @param srcPos the position in {@code src}, in Char unit, from where to start the
+     * @param srcPos the position in {@code src}, in char unit, from where to start the
      *            conversion
      * @param dstInit initial value of the destination int
      * @param dstPos the position of the LSB, in bits, in the result int
      * @param nHex the number of Chars to convert
      * @return an int containing the selected bits
-     * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 32}
+     * @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 32}
      */
     public static int hexToInt(final String src, final int srcPos, final int dstInit, final int dstPos, final int nHex) {
         if (0 == nHex) {
             return dstInit;
         }
         if ((nHex - 1) * 4 + dstPos >= 32) {
-            throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 32");
+            throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater or equal to than 32");
+        }
+        if (srcPos + nHex > src.length()) {
+            throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d  > src.length()", srcPos, nHex, src.length()));
         }
         int out = dstInit;
         for (int i = 0; i < nHex; i++) {
@@ -841,13 +844,13 @@ public static int hexToInt(final String src, final int srcPos, final int dstInit
      * bit ordering.
      *
      * @param src the hexadecimal string to convert
-     * @param srcPos the position in {@code src}, in Char unit, from where to start the
+     * @param srcPos the position in {@code src}, in char unit, from where to start the
      *            conversion
      * @param dstInit initial value of the destination long
      * @param dstPos the position of the LSB, in bits, in the result long
      * @param nHex the number of Chars to convert
      * @return a long containing the selected bits
-     * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 64}
+     * @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 64}
      */
     public static long hexToLong(final String src, final int srcPos, final long dstInit, final int dstPos,
             final int nHex) {
@@ -855,7 +858,10 @@ public static long hexToLong(final String src, final int srcPos, final long dstI
             return dstInit;
         }
         if ((nHex - 1) * 4 + dstPos >= 64) {
-            throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 64");
+            throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater or equal to than 64");
+        }
+        if (srcPos + nHex > src.length()) {
+            throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d  > src.length()", srcPos, nHex, src.length()));
         }
         long out = dstInit;
         for (int i = 0; i < nHex; i++) {
@@ -872,13 +878,13 @@ public static long hexToLong(final String src, final int srcPos, final long dstI
      * bit ordering.
      *
      * @param src the hexadecimal string to convert
-     * @param srcPos the position in {@code src}, in Char unit, from where to start the
+     * @param srcPos the position in {@code src}, in char unit, from where to start the
      *            conversion
      * @param dstInit initial value of the destination short
      * @param dstPos the position of the LSB, in bits, in the result short
      * @param nHex the number of Chars to convert
      * @return a short containing the selected bits
-     * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 16}
+     * @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 16}
      */
     public static short hexToShort(final String src, final int srcPos, final short dstInit, final int dstPos,
             final int nHex) {
@@ -886,7 +892,10 @@ public static short hexToShort(final String src, final int srcPos, final short d
             return dstInit;
         }
         if ((nHex - 1) * 4 + dstPos >= 16) {
-            throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 16");
+            throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater or equal to than 16");
+        }
+        if (srcPos + nHex > src.length()) {
+            throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d  > src.length()", srcPos, nHex, src.length()));
         }
         short out = dstInit;
         for (int i = 0; i < nHex; i++) {
diff --git a/src/test/java/org/apache/commons/lang3/ConversionTest.java b/src/test/java/org/apache/commons/lang3/ConversionTest.java
index e147e95..157e128 100644
--- a/src/test/java/org/apache/commons/lang3/ConversionTest.java
+++ b/src/test/java/org/apache/commons/lang3/ConversionTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.commons.lang3;
 
-import static org.apache.commons.lang3.LangAssertions.assertIndexOutOfBoundsException;
 import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
+import static org.apache.commons.lang3.LangAssertions.assertIndexOutOfBoundsException;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -708,6 +708,7 @@ void testHexToByte() {
         assertEquals((byte) 0xFD, Conversion.hexToByte(src, 1, (byte) 0, 0, 2));
         assertEquals((byte) 0x34, Conversion.hexToByte(src, 0, (byte) 0x34, 0, 0));
         assertEquals((byte) 0x84, Conversion.hexToByte(src, 17, (byte) 0x34, 4, 1));
+        assertThrows(IllegalArgumentException.class, () -> Conversion.hexToByte(src, src.length(), (byte) 0, 0, 1));
     }
 
     /**
@@ -722,6 +723,7 @@ void testHexToInt() {
         assertEquals(0x01C0F1FD, Conversion.hexToInt(src, 1, 0, 0, 8));
         assertEquals(0x12345679, Conversion.hexToInt(src, 0, 0x12345679, 0, 0));
         assertEquals(0x87645679, Conversion.hexToInt(src, 15, 0x12345679, 20, 3));
+        assertThrows(IllegalArgumentException.class, () -> Conversion.hexToInt(src, src.length(), 0, 0, 1));
     }
 
     /**
@@ -734,10 +736,9 @@ void testHexToLong() {
         assertEquals(0x000000000000000CL, Conversion.hexToLong(src, 0, 0L, 0, 1));
         assertEquals(0x000000001C0F1FDCL, Conversion.hexToLong(src, 0, 0L, 0, 8));
         assertEquals(0x0000000001C0F1FDL, Conversion.hexToLong(src, 1, 0L, 0, 8));
-        assertEquals(
-            0x123456798ABCDEF0L, Conversion.hexToLong(src, 0, 0x123456798ABCDEF0L, 0, 0));
-        assertEquals(
-            0x1234567876BCDEF0L, Conversion.hexToLong(src, 15, 0x123456798ABCDEF0L, 24, 3));
+        assertEquals(0x123456798ABCDEF0L, Conversion.hexToLong(src, 0, 0x123456798ABCDEF0L, 0, 0));
+        assertEquals(0x1234567876BCDEF0L, Conversion.hexToLong(src, 15, 0x123456798ABCDEF0L, 24, 3));
+        assertThrows(IllegalArgumentException.class, () -> Conversion.hexToLong(src, src.length(), 0, 0, 1));
     }
 
     /**
@@ -752,6 +753,7 @@ void testHexToShort() {
         assertEquals((short) 0xF1FD, Conversion.hexToShort(src, 1, (short) 0, 0, 4));
         assertEquals((short) 0x1234, Conversion.hexToShort(src, 0, (short) 0x1234, 0, 0));
         assertEquals((short) 0x8764, Conversion.hexToShort(src, 15, (short) 0x1234, 4, 3));
+        assertThrows(IllegalArgumentException.class, () -> Conversion.hexToShort(src, src.length(), (short) 0, 0, 1));
     }
 
     /**