Skip to content

Commit de78550

Browse files
authored
[HexUtils] Add a couple more methods (openhab#5164)
* [HexUtils] Add a couple of methods Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
1 parent c8b101f commit de78550

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

bundles/org.openhab.core/src/main/java/org/openhab/core/util/HexUtils.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
package org.openhab.core.util;
1414

15+
import java.math.BigInteger;
1516
import java.nio.charset.StandardCharsets;
1617

1718
import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -123,6 +124,47 @@ public static byte[] hexToBytes(String hexString) {
123124
return hexToBytes(hexString, "(?<=\\G.{2})");
124125
}
125126

127+
/**
128+
* Convert a white space delimited hex block to a byte array.
129+
*
130+
* @param hexBlock the hex block
131+
* @return the byte array
132+
* @throws IllegalArgumentException if a value is invalid
133+
*/
134+
public static byte[] hexBlockToBytes(String hexBlock) throws IllegalArgumentException {
135+
String plainHex = hexBlock.replaceAll("\\s+", "");
136+
if (plainHex.length() % 2 != 0) {
137+
throw new IllegalArgumentException("Hex string must have even length");
138+
}
139+
int length = plainHex.length();
140+
byte[] result = new byte[length / 2];
141+
for (int i = 0; i < length; i += 2) {
142+
int hi = Character.digit(plainHex.charAt(i), 16);
143+
int lo = Character.digit(plainHex.charAt(i + 1), 16);
144+
if (hi == -1 || lo == -1) {
145+
throw new IllegalArgumentException(
146+
"Invalid hex character: " + plainHex.charAt(i) + plainHex.charAt(i + 1));
147+
}
148+
result[i / 2] = (byte) ((hi << 4) + lo);
149+
}
150+
return result;
151+
}
152+
153+
/**
154+
* Convert a white space delimited hex block to a {@link BigInteger}.
155+
*
156+
* @param hexBlock the hex block
157+
* @return the BigInteger value
158+
* @throws IllegalArgumentException if a value is invalid
159+
*/
160+
public static BigInteger hexBlockToBigInteger(String hexBlock) throws IllegalArgumentException {
161+
String plainHex = hexBlock.replaceAll("\\s+", "");
162+
if (plainHex.length() % 2 != 0) {
163+
throw new IllegalArgumentException("Hex string must have even length");
164+
}
165+
return new BigInteger(plainHex, 16);
166+
}
167+
126168
public static byte hexToByte(byte high, byte low) {
127169
return (byte) ((unhex(high) << 4) | unhex(low));
128170
}

bundles/org.openhab.core/src/test/java/org/openhab/core/util/HexUtilsTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import static org.junit.jupiter.api.Assertions.*;
1616

17+
import java.math.BigInteger;
18+
1719
import org.eclipse.jdt.annotation.NonNullByDefault;
1820
import org.junit.jupiter.api.Test;
1921

@@ -72,4 +74,24 @@ public void testEmptyByteArray() {
7274
final byte[] output = HexUtils.hexToBytes(str);
7375
assertArrayEquals(input, output);
7476
}
77+
78+
@Test
79+
public void testHexBlockToBytes() {
80+
final String input = """
81+
0000 0000
82+
F00f
83+
""";
84+
final byte[] output = HexUtils.hexBlockToBytes(input);
85+
assertArrayEquals(new byte[] { 0, 0, 0, 0, (byte) 240, (byte) 15 }, output);
86+
}
87+
88+
@Test
89+
public void hexBlockToBigInteger() {
90+
final String input = """
91+
0000 0000
92+
F00f
93+
""";
94+
final BigInteger output = HexUtils.hexBlockToBigInteger(input);
95+
assertEquals(new BigInteger("61455"), output);
96+
}
7597
}

0 commit comments

Comments
 (0)