001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.util; 019 020import static org.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertFalse; 023import static org.junit.Assert.assertNotNull; 024import static org.junit.Assert.assertNotSame; 025import static org.junit.Assert.assertTrue; 026import static org.junit.Assert.fail; 027 028import java.io.ByteArrayInputStream; 029import java.io.ByteArrayOutputStream; 030import java.io.DataInputStream; 031import java.io.DataOutputStream; 032import java.io.IOException; 033import java.lang.reflect.Field; 034import java.lang.reflect.Modifier; 035import java.math.BigDecimal; 036import java.nio.ByteBuffer; 037import java.util.ArrayList; 038import java.util.Arrays; 039import java.util.List; 040import java.util.Random; 041import java.util.concurrent.ThreadLocalRandom; 042import org.apache.hadoop.hbase.HBaseClassTestRule; 043import org.apache.hadoop.hbase.testclassification.MediumTests; 044import org.apache.hadoop.hbase.testclassification.MiscTests; 045import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent; 046import org.apache.hadoop.io.WritableUtils; 047import org.junit.Assert; 048import org.junit.ClassRule; 049import org.junit.Test; 050import org.junit.experimental.categories.Category; 051 052@Category({ MiscTests.class, MediumTests.class }) 053public class TestBytes { 054 @ClassRule 055 public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestBytes.class); 056 057 private static void setUnsafe(boolean value) throws Exception { 058 Field field = Bytes.class.getDeclaredField("UNSAFE_UNALIGNED"); 059 field.setAccessible(true); 060 Field modifiersField = Field.class.getDeclaredField("modifiers"); 061 modifiersField.setAccessible(true); 062 int oldModifiers = field.getModifiers(); 063 modifiersField.setInt(field, oldModifiers & ~Modifier.FINAL); 064 try { 065 field.set(null, value); 066 } finally { 067 modifiersField.setInt(field, oldModifiers); 068 } 069 assertEquals(Bytes.UNSAFE_UNALIGNED, value); 070 } 071 072 @Test 073 public void testShort() throws Exception { 074 testShort(false); 075 } 076 077 @Test 078 public void testShortUnsafe() throws Exception { 079 testShort(true); 080 } 081 082 private static void testShort(boolean unsafe) throws Exception { 083 setUnsafe(unsafe); 084 try { 085 for (short n : Arrays.asList(Short.MIN_VALUE, (short) -100, (short) -1, (short) 0, (short) 1, 086 (short) 300, Short.MAX_VALUE)) { 087 byte[] bytes = Bytes.toBytes(n); 088 assertEquals(Bytes.toShort(bytes, 0, bytes.length), n); 089 } 090 } finally { 091 setUnsafe(HBasePlatformDependent.unaligned()); 092 } 093 } 094 095 @Test 096 public void testNullHashCode() { 097 byte[] b = null; 098 Exception ee = null; 099 try { 100 Bytes.hashCode(b); 101 } catch (Exception e) { 102 ee = e; 103 } 104 assertNotNull(ee); 105 } 106 107 @Test 108 public void testAdd() { 109 byte[] a = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 110 byte[] b = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 111 byte[] c = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; 112 byte[] result1 = Bytes.add(a, b, c); 113 byte[] result2 = Bytes.add(new byte[][] { a, b, c }); 114 assertEquals(0, Bytes.compareTo(result1, result2)); 115 } 116 117 @Test 118 public void testSplit() { 119 byte[] lowest = Bytes.toBytes("AAA"); 120 byte[] middle = Bytes.toBytes("CCC"); 121 byte[] highest = Bytes.toBytes("EEE"); 122 byte[][] parts = Bytes.split(lowest, highest, 1); 123 for (byte[] bytes : parts) { 124 System.out.println(Bytes.toString(bytes)); 125 } 126 assertEquals(3, parts.length); 127 assertTrue(Bytes.equals(parts[1], middle)); 128 // Now divide into three parts. Change highest so split is even. 129 highest = Bytes.toBytes("DDD"); 130 parts = Bytes.split(lowest, highest, 2); 131 for (byte[] part : parts) { 132 System.out.println(Bytes.toString(part)); 133 } 134 assertEquals(4, parts.length); 135 // Assert that 3rd part is 'CCC'. 136 assertTrue(Bytes.equals(parts[2], middle)); 137 } 138 139 @Test 140 public void testSplit2() { 141 // More split tests. 142 byte[] lowest = Bytes.toBytes("http://A"); 143 byte[] highest = Bytes.toBytes("http://z"); 144 byte[] middle = Bytes.toBytes("http://]"); 145 byte[][] parts = Bytes.split(lowest, highest, 1); 146 for (byte[] part : parts) { 147 System.out.println(Bytes.toString(part)); 148 } 149 assertEquals(3, parts.length); 150 assertTrue(Bytes.equals(parts[1], middle)); 151 } 152 153 @Test 154 public void testSplit3() { 155 // Test invalid split cases 156 byte[] low = { 1, 1, 1 }; 157 byte[] high = { 1, 1, 3 }; 158 159 // If swapped, should throw IAE 160 try { 161 Bytes.split(high, low, 1); 162 fail("Should not be able to split if low > high"); 163 } catch (IllegalArgumentException iae) { 164 // Correct 165 } 166 167 // Single split should work 168 byte[][] parts = Bytes.split(low, high, 1); 169 for (int i = 0; i < parts.length; i++) { 170 System.out.println("" + i + " -> " + Bytes.toStringBinary(parts[i])); 171 } 172 assertEquals("Returned split should have 3 parts but has " + parts.length, 3, parts.length); 173 174 // If split more than once, use additional byte to split 175 parts = Bytes.split(low, high, 2); 176 assertNotNull("Split with an additional byte", parts); 177 assertEquals(parts.length, low.length + 1); 178 179 // Split 0 times should throw IAE 180 try { 181 Bytes.split(low, high, 0); 182 fail("Should not be able to split 0 times"); 183 } catch (IllegalArgumentException iae) { 184 // Correct 185 } 186 } 187 188 @Test 189 public void testToInt() { 190 int[] ints = { -1, 123, Integer.MIN_VALUE, Integer.MAX_VALUE }; 191 for (int anInt : ints) { 192 byte[] b = Bytes.toBytes(anInt); 193 assertEquals(anInt, Bytes.toInt(b)); 194 byte[] b2 = bytesWithOffset(b); 195 assertEquals(anInt, Bytes.toInt(b2, 1)); 196 assertEquals(anInt, Bytes.toInt(b2, 1, Bytes.SIZEOF_INT)); 197 } 198 } 199 200 @Test 201 public void testToLong() { 202 long[] longs = { -1L, 123L, Long.MIN_VALUE, Long.MAX_VALUE }; 203 for (long aLong : longs) { 204 byte[] b = Bytes.toBytes(aLong); 205 assertEquals(aLong, Bytes.toLong(b)); 206 byte[] b2 = bytesWithOffset(b); 207 assertEquals(aLong, Bytes.toLong(b2, 1)); 208 assertEquals(aLong, Bytes.toLong(b2, 1, Bytes.SIZEOF_LONG)); 209 } 210 } 211 212 @Test 213 public void testToFloat() { 214 float[] floats = { -1f, 123.123f, Float.MAX_VALUE }; 215 for (float aFloat : floats) { 216 byte[] b = Bytes.toBytes(aFloat); 217 assertEquals(aFloat, Bytes.toFloat(b), 0.0f); 218 byte[] b2 = bytesWithOffset(b); 219 assertEquals(aFloat, Bytes.toFloat(b2, 1), 0.0f); 220 } 221 } 222 223 @Test 224 public void testToDouble() { 225 double[] doubles = { Double.MIN_VALUE, Double.MAX_VALUE }; 226 for (double aDouble : doubles) { 227 byte[] b = Bytes.toBytes(aDouble); 228 assertEquals(aDouble, Bytes.toDouble(b), 0.0); 229 byte[] b2 = bytesWithOffset(b); 230 assertEquals(aDouble, Bytes.toDouble(b2, 1), 0.0); 231 } 232 } 233 234 @Test 235 public void testToBigDecimal() { 236 BigDecimal[] decimals = 237 { new BigDecimal("-1"), new BigDecimal("123.123"), new BigDecimal("123123123123") }; 238 for (BigDecimal decimal : decimals) { 239 byte[] b = Bytes.toBytes(decimal); 240 assertEquals(decimal, Bytes.toBigDecimal(b)); 241 byte[] b2 = bytesWithOffset(b); 242 assertEquals(decimal, Bytes.toBigDecimal(b2, 1, b.length)); 243 } 244 } 245 246 private byte[] bytesWithOffset(byte[] src) { 247 // add one byte in front to test offset 248 byte[] result = new byte[src.length + 1]; 249 result[0] = (byte) 0xAA; 250 System.arraycopy(src, 0, result, 1, src.length); 251 return result; 252 } 253 254 @Test 255 public void testToBytesForByteBuffer() { 256 byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 257 ByteBuffer target = ByteBuffer.wrap(array); 258 target.position(2); 259 target.limit(7); 260 261 byte[] actual = Bytes.toBytes(target); 262 byte[] expected = { 0, 1, 2, 3, 4, 5, 6 }; 263 assertArrayEquals(expected, actual); 264 assertEquals(2, target.position()); 265 assertEquals(7, target.limit()); 266 267 ByteBuffer target2 = target.slice(); 268 assertEquals(0, target2.position()); 269 assertEquals(5, target2.limit()); 270 271 byte[] actual2 = Bytes.toBytes(target2); 272 byte[] expected2 = { 2, 3, 4, 5, 6 }; 273 assertArrayEquals(expected2, actual2); 274 assertEquals(0, target2.position()); 275 assertEquals(5, target2.limit()); 276 } 277 278 @Test 279 public void testGetBytesForByteBuffer() { 280 byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 281 ByteBuffer target = ByteBuffer.wrap(array); 282 target.position(2); 283 target.limit(7); 284 285 byte[] actual = Bytes.getBytes(target); 286 byte[] expected = { 2, 3, 4, 5, 6 }; 287 assertArrayEquals(expected, actual); 288 assertEquals(2, target.position()); 289 assertEquals(7, target.limit()); 290 } 291 292 @Test 293 public void testReadAsVLong() throws Exception { 294 long[] longs = { -1L, 123L, Long.MIN_VALUE, Long.MAX_VALUE }; 295 for (long aLong : longs) { 296 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 297 DataOutputStream output = new DataOutputStream(baos); 298 WritableUtils.writeVLong(output, aLong); 299 byte[] long_bytes_no_offset = baos.toByteArray(); 300 assertEquals(aLong, Bytes.readAsVLong(long_bytes_no_offset, 0)); 301 byte[] long_bytes_with_offset = bytesWithOffset(long_bytes_no_offset); 302 assertEquals(aLong, Bytes.readAsVLong(long_bytes_with_offset, 1)); 303 } 304 } 305 306 @Test 307 public void testToStringBinaryForBytes() { 308 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 }; 309 String actual = Bytes.toStringBinary(array); 310 String expected = "09azAZ@\\x01"; 311 assertEquals(expected, actual); 312 313 String actual2 = Bytes.toStringBinary(array, 2, 3); 314 String expected2 = "azA"; 315 assertEquals(expected2, actual2); 316 } 317 318 @Test 319 public void testToStringBinaryForArrayBasedByteBuffer() { 320 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 }; 321 ByteBuffer target = ByteBuffer.wrap(array); 322 String actual = Bytes.toStringBinary(target); 323 String expected = "09azAZ@\\x01"; 324 assertEquals(expected, actual); 325 } 326 327 @Test 328 public void testToStringBinaryForReadOnlyByteBuffer() { 329 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 }; 330 ByteBuffer target = ByteBuffer.wrap(array).asReadOnlyBuffer(); 331 String actual = Bytes.toStringBinary(target); 332 String expected = "09azAZ@\\x01"; 333 assertEquals(expected, actual); 334 } 335 336 @Test 337 public void testBinarySearch() { 338 byte[][] arr = { { 1 }, { 3 }, { 5 }, { 7 }, { 9 }, { 11 }, { 13 }, { 15 }, }; 339 byte[] key1 = { 3, 1 }; 340 byte[] key2 = { 4, 9 }; 341 byte[] key2_2 = { 4 }; 342 byte[] key3 = { 5, 11 }; 343 byte[] key4 = { 0 }; 344 byte[] key5 = { 2 }; 345 346 assertEquals(1, Bytes.binarySearch(arr, key1, 0, 1)); 347 assertEquals(0, Bytes.binarySearch(arr, key1, 1, 1)); 348 assertEquals(-(2 + 1), Arrays.binarySearch(arr, key2_2, Bytes.BYTES_COMPARATOR)); 349 assertEquals(-(2 + 1), Bytes.binarySearch(arr, key2, 0, 1)); 350 assertEquals(4, Bytes.binarySearch(arr, key2, 1, 1)); 351 assertEquals(2, Bytes.binarySearch(arr, key3, 0, 1)); 352 assertEquals(5, Bytes.binarySearch(arr, key3, 1, 1)); 353 assertEquals(-1, Bytes.binarySearch(arr, key4, 0, 1)); 354 assertEquals(-2, Bytes.binarySearch(arr, key5, 0, 1)); 355 356 // Search for values to the left and to the right of each item in the array. 357 for (int i = 0; i < arr.length; ++i) { 358 assertEquals(-(i + 1), Bytes.binarySearch(arr, new byte[] { (byte) (arr[i][0] - 1) }, 0, 1)); 359 assertEquals(-(i + 2), Bytes.binarySearch(arr, new byte[] { (byte) (arr[i][0] + 1) }, 0, 1)); 360 } 361 } 362 363 @Test 364 public void testToStringBytesBinaryReversible() { 365 byte[] randomBytes = new byte[1000]; 366 for (int i = 0; i < 1000; i++) { 367 Bytes.random(randomBytes); 368 verifyReversibleForBytes(randomBytes); 369 } 370 // some specific cases 371 verifyReversibleForBytes(new byte[] {}); 372 verifyReversibleForBytes(new byte[] { '\\', 'x', 'A', 'D' }); 373 verifyReversibleForBytes(new byte[] { '\\', 'x', 'A', 'D', '\\' }); 374 } 375 376 private void verifyReversibleForBytes(byte[] originalBytes) { 377 String convertedString = Bytes.toStringBinary(originalBytes); 378 byte[] convertedBytes = Bytes.toBytesBinary(convertedString); 379 if (Bytes.compareTo(originalBytes, convertedBytes) != 0) { 380 fail("Not reversible for\nbyte[]: " + Arrays.toString(originalBytes) + ",\nStringBinary: " 381 + convertedString); 382 } 383 } 384 385 @Test 386 public void testStartsWith() { 387 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("h"))); 388 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes(""))); 389 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("hello"))); 390 assertFalse(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("helloworld"))); 391 assertFalse(Bytes.startsWith(Bytes.toBytes(""), Bytes.toBytes("hello"))); 392 } 393 394 @Test 395 public void testIncrementBytes() { 396 assertTrue(checkTestIncrementBytes(10, 1)); 397 assertTrue(checkTestIncrementBytes(12, 123435445)); 398 assertTrue(checkTestIncrementBytes(124634654, 1)); 399 assertTrue(checkTestIncrementBytes(10005460, 5005645)); 400 assertTrue(checkTestIncrementBytes(1, -1)); 401 assertTrue(checkTestIncrementBytes(10, -1)); 402 assertTrue(checkTestIncrementBytes(10, -5)); 403 assertTrue(checkTestIncrementBytes(1005435000, -5)); 404 assertTrue(checkTestIncrementBytes(10, -43657655)); 405 assertTrue(checkTestIncrementBytes(-1, 1)); 406 assertTrue(checkTestIncrementBytes(-26, 5034520)); 407 assertTrue(checkTestIncrementBytes(-10657200, 5)); 408 assertTrue(checkTestIncrementBytes(-12343250, 45376475)); 409 assertTrue(checkTestIncrementBytes(-10, -5)); 410 assertTrue(checkTestIncrementBytes(-12343250, -5)); 411 assertTrue(checkTestIncrementBytes(-12, -34565445)); 412 assertTrue(checkTestIncrementBytes(-1546543452, -34565445)); 413 } 414 415 private static boolean checkTestIncrementBytes(long val, long amount) { 416 byte[] value = Bytes.toBytes(val); 417 byte[] testValue = { -1, -1, -1, -1, -1, -1, -1, -1 }; 418 if (value[0] > 0) { 419 testValue = new byte[Bytes.SIZEOF_LONG]; 420 } 421 System.arraycopy(value, 0, testValue, testValue.length - value.length, value.length); 422 423 long incrementResult = Bytes.toLong(Bytes.incrementBytes(value, amount)); 424 425 return (Bytes.toLong(testValue) + amount) == incrementResult; 426 } 427 428 @Test 429 public void testFixedSizeString() throws IOException { 430 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 431 DataOutputStream dos = new DataOutputStream(baos); 432 Bytes.writeStringFixedSize(dos, "Hello", 5); 433 Bytes.writeStringFixedSize(dos, "World", 18); 434 Bytes.writeStringFixedSize(dos, "", 9); 435 436 try { 437 // Use a long dash which is three bytes in UTF-8. If encoding happens 438 // using ISO-8859-1, this will fail. 439 Bytes.writeStringFixedSize(dos, "Too\u2013Long", 9); 440 fail("Exception expected"); 441 } catch (IOException ex) { 442 assertEquals( 443 "Trying to write 10 bytes (Too\\xE2\\x80\\x93Long) into a field of " + "length 9", 444 ex.getMessage()); 445 } 446 447 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 448 DataInputStream dis = new DataInputStream(bais); 449 assertEquals("Hello", Bytes.readStringFixedSize(dis, 5)); 450 assertEquals("World", Bytes.readStringFixedSize(dis, 18)); 451 assertEquals("", Bytes.readStringFixedSize(dis, 9)); 452 } 453 454 @Test 455 public void testCopy() { 456 byte[] bytes = Bytes.toBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 457 byte[] copy = Bytes.copy(bytes); 458 assertNotSame(bytes, copy); 459 assertTrue(Bytes.equals(bytes, copy)); 460 } 461 462 @Test 463 public void testToBytesBinaryTrailingBackslashes() { 464 try { 465 Bytes.toBytesBinary("abc\\x00\\x01\\"); 466 } catch (StringIndexOutOfBoundsException ex) { 467 fail("Illegal string access: " + ex.getMessage()); 468 } 469 } 470 471 @Test 472 public void testToStringBinary_toBytesBinary_Reversable() { 473 String bytes = Bytes.toStringBinary(Bytes.toBytes(2.17)); 474 assertEquals(2.17, Bytes.toDouble(Bytes.toBytesBinary(bytes)), 0); 475 } 476 477 @Test 478 public void testUnsignedBinarySearch() { 479 byte[] bytes = new byte[] { 0, 5, 123, 127, -128, -100, -1 }; 480 Assert.assertEquals(1, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) 5)); 481 Assert.assertEquals(3, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) 127)); 482 Assert.assertEquals(4, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -128)); 483 Assert.assertEquals(5, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -100)); 484 Assert.assertEquals(6, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -1)); 485 Assert.assertEquals(-1 - 1, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) 2)); 486 Assert.assertEquals(-6 - 1, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -5)); 487 } 488 489 @Test 490 public void testUnsignedIncrement() { 491 byte[] a = Bytes.toBytes(0); 492 int a2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(a), 0); 493 Assert.assertEquals(1, a2); 494 495 byte[] b = Bytes.toBytes(-1); 496 byte[] actual = Bytes.unsignedCopyAndIncrement(b); 497 Assert.assertNotSame(b, actual); 498 byte[] expected = new byte[] { 1, 0, 0, 0, 0 }; 499 assertArrayEquals(expected, actual); 500 501 byte[] c = Bytes.toBytes(255);// should wrap to the next significant byte 502 int c2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(c), 0); 503 Assert.assertEquals(256, c2); 504 } 505 506 @Test 507 public void testIndexOf() { 508 byte[] array = Bytes.toBytes("hello"); 509 assertEquals(1, Bytes.indexOf(array, (byte) 'e')); 510 assertEquals(4, Bytes.indexOf(array, (byte) 'o')); 511 assertEquals(-1, Bytes.indexOf(array, (byte) 'a')); 512 assertEquals(0, Bytes.indexOf(array, Bytes.toBytes("hel"))); 513 assertEquals(2, Bytes.indexOf(array, Bytes.toBytes("ll"))); 514 assertEquals(-1, Bytes.indexOf(array, Bytes.toBytes("hll"))); 515 } 516 517 @Test 518 public void testContains() { 519 byte[] array = Bytes.toBytes("hello world"); 520 assertTrue(Bytes.contains(array, (byte) 'e')); 521 assertTrue(Bytes.contains(array, (byte) 'd')); 522 assertFalse(Bytes.contains(array, (byte) 'a')); 523 assertTrue(Bytes.contains(array, Bytes.toBytes("world"))); 524 assertTrue(Bytes.contains(array, Bytes.toBytes("ello"))); 525 assertFalse(Bytes.contains(array, Bytes.toBytes("owo"))); 526 } 527 528 @Test 529 public void testZero() { 530 byte[] array = Bytes.toBytes("hello"); 531 Bytes.zero(array); 532 for (byte b : array) { 533 assertEquals(0, b); 534 } 535 array = Bytes.toBytes("hello world"); 536 Bytes.zero(array, 2, 7); 537 assertFalse(array[0] == 0); 538 assertFalse(array[1] == 0); 539 for (int i = 2; i < 9; i++) { 540 assertEquals(0, array[i]); 541 } 542 for (int i = 9; i < array.length; i++) { 543 assertFalse(array[i] == 0); 544 } 545 } 546 547 @Test 548 public void testPutBuffer() { 549 byte[] b = new byte[100]; 550 for (byte i = 0; i < 100; i++) { 551 Bytes.putByteBuffer(b, i, ByteBuffer.wrap(new byte[] { i })); 552 } 553 for (byte i = 0; i < 100; i++) { 554 Assert.assertEquals(i, b[i]); 555 } 556 } 557 558 @Test 559 public void testToFromHex() { 560 List<String> testStrings = new ArrayList<>(8); 561 testStrings.addAll(Arrays.asList("", "00", "A0", "ff", "FFffFFFFFFFFFF", "12", 562 "0123456789abcdef", "283462839463924623984692834692346ABCDFEDDCA0")); 563 for (String testString : testStrings) { 564 byte[] byteData = Bytes.fromHex(testString); 565 Assert.assertEquals(testString.length() / 2, byteData.length); 566 String result = Bytes.toHex(byteData); 567 Assert.assertTrue(testString.equalsIgnoreCase(result)); 568 } 569 570 List<byte[]> testByteData = new ArrayList<>(5); 571 testByteData.addAll(Arrays.asList(new byte[0], new byte[1], new byte[10], 572 new byte[] { 1, 2, 3, 4, 5 }, new byte[] { (byte) 0xFF })); 573 Random rand = ThreadLocalRandom.current(); 574 for (int i = 0; i < 20; i++) { 575 byte[] bytes = new byte[rand.nextInt(100)]; 576 Bytes.random(bytes); 577 testByteData.add(bytes); 578 } 579 580 for (byte[] testData : testByteData) { 581 String hexString = Bytes.toHex(testData); 582 Assert.assertEquals(testData.length * 2, hexString.length()); 583 byte[] result = Bytes.fromHex(hexString); 584 assertArrayEquals(testData, result); 585 } 586 } 587}