1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.lang3; 18 19 import java.util.UUID; 20 21 22 /** 23 * Static methods to convert a type into another, with endianness and bit ordering awareness. 24 * 25 * <p> 26 * The methods names follow a naming rule:<br> 27 * {@code <source type>[source endianness][source bit ordering]To<destination type>[destination endianness][destination bit ordering]} 28 * </p> 29 * <p> 30 * Source/destination type fields is one of the following: 31 * </p> 32 * <ul> 33 * <li>binary: an array of booleans</li> 34 * <li>byte or byteArray</li> 35 * <li>int or intArray</li> 36 * <li>long or longArray</li> 37 * <li>hex: a String containing hexadecimal digits (lowercase in destination)</li> 38 * <li>hexDigit: a Char containing a hexadecimal digit (lowercase in destination)</li> 39 * <li>uuid</li> 40 * </ul> 41 * <p> 42 * Endianness field: little endian is the default, in this case the field is absent. In case of 43 * big endian, the field is "Be".<br> Bit ordering: Lsb0 is the default, in this case the field 44 * is absent. In case of Msb0, the field is "Msb0". 45 * </p> 46 * <p> 47 * Example: intBeMsb0ToHex convert an int with big endian byte order and Msb0 bit order into its 48 * hexadecimal string representation 49 * </p> 50 * <p> 51 * Most of the methods provide only default encoding for destination, this limits the number of 52 * ways to do one thing. Unless you are dealing with data from/to outside of the JVM platform, 53 * you should not need to use "Be" and "Msb0" methods. 54 * </p> 55 * <p> 56 * Development status: work on going, only a part of the little endian, Lsb0 methods implemented 57 * so far. 58 * </p> 59 * 60 * @since 3.2 61 */ 62 63 public class Conversion { 64 65 private static final boolean[] TTTT = {true, true, true, true}; 66 private static final boolean[] FTTT = {false, true, true, true}; 67 private static final boolean[] TFTT = {true, false, true, true}; 68 private static final boolean[] FFTT = {false, false, true, true}; 69 private static final boolean[] TTFT = {true, true, false, true}; 70 private static final boolean[] FTFT = {false, true, false, true}; 71 private static final boolean[] TFFT = {true, false, false, true}; 72 private static final boolean[] FFFT = {false, false, false, true}; 73 private static final boolean[] TTTF = {true, true, true, false}; 74 private static final boolean[] FTTF = {false, true, true, false}; 75 private static final boolean[] TFTF = {true, false, true, false}; 76 private static final boolean[] FFTF = {false, false, true, false}; 77 private static final boolean[] TTFF = {true, true, false, false}; 78 private static final boolean[] FTFF = {false, true, false, false}; 79 private static final boolean[] TFFF = {true, false, false, false}; 80 private static final boolean[] FFFF = {false, false, false, false}; 81 82 /** 83 * Converts a hexadecimal digit into an int using the default (Lsb0) bit ordering. 84 * 85 * <p> 86 * '1' is converted to 1 87 * </p> 88 * 89 * @param hexDigit the hexadecimal digit to convert 90 * @return an int equals to {@code hexDigit} 91 * @throws IllegalArgumentException if {@code hexDigit} is not a hexadecimal digit 92 */ hexDigitToInt(final char hexDigit)93 public static int hexDigitToInt(final char hexDigit) { 94 final int digit = Character.digit(hexDigit, 16); 95 if (digit < 0) { 96 throw new IllegalArgumentException("Cannot interpret '" + hexDigit + "' as a hexadecimal digit"); 97 } 98 return digit; 99 } 100 101 /** 102 * Converts a hexadecimal digit into an int using the Msb0 bit ordering. 103 * 104 * <p> 105 * '1' is converted to 8 106 * </p> 107 * 108 * @param hexDigit the hexadecimal digit to convert 109 * @return an int equals to {@code hexDigit} 110 * @throws IllegalArgumentException if {@code hexDigit} is not a hexadecimal digit 111 */ hexDigitMsb0ToInt(final char hexDigit)112 public static int hexDigitMsb0ToInt(final char hexDigit) { 113 switch (hexDigit) { 114 case '0': 115 return 0x0; 116 case '1': 117 return 0x8; 118 case '2': 119 return 0x4; 120 case '3': 121 return 0xC; 122 case '4': 123 return 0x2; 124 case '5': 125 return 0xA; 126 case '6': 127 return 0x6; 128 case '7': 129 return 0xE; 130 case '8': 131 return 0x1; 132 case '9': 133 return 0x9; 134 case 'a':// fall through 135 case 'A': 136 return 0x5; 137 case 'b':// fall through 138 case 'B': 139 return 0xD; 140 case 'c':// fall through 141 case 'C': 142 return 0x3; 143 case 'd':// fall through 144 case 'D': 145 return 0xB; 146 case 'e':// fall through 147 case 'E': 148 return 0x7; 149 case 'f':// fall through 150 case 'F': 151 return 0xF; 152 default: 153 throw new IllegalArgumentException("Cannot interpret '" + hexDigit + "' as a hexadecimal digit"); 154 } 155 } 156 157 /** 158 * Converts a hexadecimal digit into binary (represented as boolean array) using the default 159 * (Lsb0) bit ordering. 160 * 161 * <p> 162 * '1' is converted as follow: (1, 0, 0, 0) 163 * </p> 164 * 165 * @param hexDigit the hexadecimal digit to convert 166 * @return a boolean array with the binary representation of {@code hexDigit} 167 * @throws IllegalArgumentException if {@code hexDigit} is not a hexadecimal digit 168 */ hexDigitToBinary(final char hexDigit)169 public static boolean[] hexDigitToBinary(final char hexDigit) { 170 switch (hexDigit) { 171 case '0': 172 return FFFF.clone(); 173 case '1': 174 return TFFF.clone(); 175 case '2': 176 return FTFF.clone(); 177 case '3': 178 return TTFF.clone(); 179 case '4': 180 return FFTF.clone(); 181 case '5': 182 return TFTF.clone(); 183 case '6': 184 return FTTF.clone(); 185 case '7': 186 return TTTF.clone(); 187 case '8': 188 return FFFT.clone(); 189 case '9': 190 return TFFT.clone(); 191 case 'a':// fall through 192 case 'A': 193 return FTFT.clone(); 194 case 'b':// fall through 195 case 'B': 196 return TTFT.clone(); 197 case 'c':// fall through 198 case 'C': 199 return FFTT.clone(); 200 case 'd':// fall through 201 case 'D': 202 return TFTT.clone(); 203 case 'e':// fall through 204 case 'E': 205 return FTTT.clone(); 206 case 'f':// fall through 207 case 'F': 208 return TTTT.clone(); 209 default: 210 throw new IllegalArgumentException("Cannot interpret '" + hexDigit + "' as a hexadecimal digit"); 211 } 212 } 213 214 /** 215 * Converts a hexadecimal digit into binary (represented as boolean array) using the Msb0 216 * bit ordering. 217 * 218 * <p> 219 * '1' is converted as follow: (0, 0, 0, 1) 220 * </p> 221 * 222 * @param hexDigit the hexadecimal digit to convert 223 * @return a boolean array with the binary representation of {@code hexDigit} 224 * @throws IllegalArgumentException if {@code hexDigit} is not a hexadecimal digit 225 */ hexDigitMsb0ToBinary(final char hexDigit)226 public static boolean[] hexDigitMsb0ToBinary(final char hexDigit) { 227 switch (hexDigit) { 228 case '0': 229 return FFFF.clone(); 230 case '1': 231 return FFFT.clone(); 232 case '2': 233 return FFTF.clone(); 234 case '3': 235 return FFTT.clone(); 236 case '4': 237 return FTFF.clone(); 238 case '5': 239 return FTFT.clone(); 240 case '6': 241 return FTTF.clone(); 242 case '7': 243 return FTTT.clone(); 244 case '8': 245 return TFFF.clone(); 246 case '9': 247 return TFFT.clone(); 248 case 'a':// fall through 249 case 'A': 250 return TFTF.clone(); 251 case 'b':// fall through 252 case 'B': 253 return TFTT.clone(); 254 case 'c':// fall through 255 case 'C': 256 return TTFF.clone(); 257 case 'd':// fall through 258 case 'D': 259 return TTFT.clone(); 260 case 'e':// fall through 261 case 'E': 262 return TTTF.clone(); 263 case 'f':// fall through 264 case 'F': 265 return TTTT.clone(); 266 default: 267 throw new IllegalArgumentException("Cannot interpret '" + hexDigit + "' as a hexadecimal digit"); 268 } 269 } 270 271 /** 272 * Converts binary (represented as boolean array) to a hexadecimal digit using the default 273 * (Lsb0) bit ordering. 274 * 275 * <p> 276 * (1, 0, 0, 0) is converted as follow: '1' 277 * </p> 278 * 279 * @param src the binary to convert 280 * @return a hexadecimal digit representing the selected bits 281 * @throws IllegalArgumentException if {@code src} is empty 282 * @throws NullPointerException if {@code src} is {@code null} 283 */ binaryToHexDigit(final boolean[] src)284 public static char binaryToHexDigit(final boolean[] src) { 285 return binaryToHexDigit(src, 0); 286 } 287 288 /** 289 * Converts binary (represented as boolean array) to a hexadecimal digit using the default 290 * (Lsb0) bit ordering. 291 * 292 * <p> 293 * (1, 0, 0, 0) is converted as follow: '1' 294 * </p> 295 * 296 * @param src the binary to convert 297 * @param srcPos the position of the lsb to start the conversion 298 * @return a hexadecimal digit representing the selected bits 299 * @throws IllegalArgumentException if {@code src} is empty 300 * @throws NullPointerException if {@code src} is {@code null} 301 */ binaryToHexDigit(final boolean[] src, final int srcPos)302 public static char binaryToHexDigit(final boolean[] src, final int srcPos) { 303 if (src.length == 0) { 304 throw new IllegalArgumentException("Cannot convert an empty array."); 305 } 306 if (src.length > srcPos + 3 && src[srcPos + 3]) { 307 if (src[srcPos + 2]) { 308 if (src[srcPos + 1]) { 309 return src[srcPos] ? 'f' : 'e'; 310 } 311 return src[srcPos] ? 'd' : 'c'; 312 } 313 if (src[srcPos + 1]) { 314 return src[srcPos] ? 'b' : 'a'; 315 } 316 return src[srcPos] ? '9' : '8'; 317 } 318 if (src.length > srcPos + 2 && src[srcPos + 2]) { 319 if (src[srcPos + 1]) { 320 return src[srcPos] ? '7' : '6'; 321 } 322 return src[srcPos] ? '5' : '4'; 323 } 324 if (src.length > srcPos + 1 && src[srcPos + 1]) { 325 return src[srcPos] ? '3' : '2'; 326 } 327 return src[srcPos] ? '1' : '0'; 328 } 329 330 /** 331 * Converts binary (represented as boolean array) to a hexadecimal digit using the Msb0 bit 332 * ordering. 333 * 334 * <p> 335 * (1, 0, 0, 0) is converted as follow: '8' 336 * </p> 337 * 338 * @param src the binary to convert 339 * @return a hexadecimal digit representing the selected bits 340 * @throws IllegalArgumentException if {@code src} is empty, {@code src.length < 4} or 341 * {@code src.length > 8} 342 * @throws NullPointerException if {@code src} is {@code null} 343 */ binaryToHexDigitMsb0_4bits(final boolean[] src)344 public static char binaryToHexDigitMsb0_4bits(final boolean[] src) { 345 return binaryToHexDigitMsb0_4bits(src, 0); 346 } 347 348 /** 349 * Converts binary (represented as boolean array) to a hexadecimal digit using the Msb0 bit 350 * ordering. 351 * 352 * <p> 353 * (1, 0, 0, 0) is converted as follow: '8' (1, 0, 0, 1, 1, 0, 1, 0) with srcPos = 3 is converted 354 * to 'D' 355 * </p> 356 * 357 * @param src the binary to convert 358 * @param srcPos the position of the lsb to start the conversion 359 * @return a hexadecimal digit representing the selected bits 360 * @throws IllegalArgumentException if {@code src} is empty, {@code src.length > 8} or 361 * {@code src.length - srcPos < 4} 362 * @throws NullPointerException if {@code src} is {@code null} 363 */ binaryToHexDigitMsb0_4bits(final boolean[] src, final int srcPos)364 public static char binaryToHexDigitMsb0_4bits(final boolean[] src, final int srcPos) { 365 if (src.length > 8) { 366 throw new IllegalArgumentException("src.length>8: src.length=" + src.length); 367 } 368 if (src.length - srcPos < 4) { 369 throw new IllegalArgumentException("src.length-srcPos<4: src.length=" + src.length + ", srcPos=" + srcPos); 370 } 371 if (src[srcPos + 3]) { 372 if (src[srcPos + 2]) { 373 if (src[srcPos + 1]) { 374 return src[srcPos] ? 'f' : '7'; 375 } 376 return src[srcPos] ? 'b' : '3'; 377 } 378 if (src[srcPos + 1]) { 379 return src[srcPos] ? 'd' : '5'; 380 } 381 return src[srcPos] ? '9' : '1'; 382 } 383 if (src[srcPos + 2]) { 384 if (src[srcPos + 1]) { 385 return src[srcPos] ? 'e' : '6'; 386 } 387 return src[srcPos] ? 'a' : '2'; 388 } 389 if (src[srcPos + 1]) { 390 return src[srcPos] ? 'c' : '4'; 391 } 392 return src[srcPos] ? '8' : '0'; 393 } 394 395 /** 396 * Converts the first 4 bits of a binary (represented as boolean array) in big endian Msb0 397 * bit ordering to a hexadecimal digit. 398 * 399 * <p> 400 * (1, 0, 0, 0) is converted as follow: '8' (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0) is converted 401 * to '4' 402 * </p> 403 * 404 * @param src the binary to convert 405 * @return a hexadecimal digit representing the selected bits 406 * @throws IllegalArgumentException if {@code src} is empty 407 * @throws NullPointerException if {@code src} is {@code null} 408 */ binaryBeMsb0ToHexDigit(final boolean[] src)409 public static char binaryBeMsb0ToHexDigit(final boolean[] src) { 410 return binaryBeMsb0ToHexDigit(src, 0); 411 } 412 413 /** 414 * Converts a binary (represented as boolean array) in big endian Msb0 bit ordering to a 415 * hexadecimal digit. 416 * 417 * <p> 418 * (1, 0, 0, 0) with srcPos = 0 is converted as follow: '8' (1, 0, 0, 0, 0, 0, 0, 0, 419 * 0, 0, 0, 1, 0, 1, 0, 0) with srcPos = 2 is converted to '5' 420 * </p> 421 * 422 * @param src the binary to convert 423 * @param srcPos the position of the lsb to start the conversion 424 * @return a hexadecimal digit representing the selected bits 425 * @throws IllegalArgumentException if {@code src} is empty 426 * @throws NullPointerException if {@code src} is {@code null} 427 * @throws IndexOutOfBoundsException if {@code srcPos} is outside the array. 428 */ binaryBeMsb0ToHexDigit(final boolean[] src, final int srcPos)429 public static char binaryBeMsb0ToHexDigit(final boolean[] src, final int srcPos) { 430 // JDK 9: Objects.checkIndex(int index, int length) 431 if (Integer.compareUnsigned(srcPos, src.length) >= 0) { 432 // Throw the correct exception 433 if (src.length == 0) { 434 throw new IllegalArgumentException("Cannot convert an empty array."); 435 } 436 throw new IndexOutOfBoundsException(srcPos + " is not within array length " + src.length); 437 } 438 // Little-endian bit 0 position 439 final int pos = src.length - 1 - srcPos; 440 if (3 <= pos && src[pos - 3]) { 441 if (src[pos - 2]) { 442 if (src[pos - 1]) { 443 return src[pos] ? 'f' : 'e'; 444 } 445 return src[pos] ? 'd' : 'c'; 446 } 447 if (src[pos - 1]) { 448 return src[pos] ? 'b' : 'a'; 449 } 450 return src[pos] ? '9' : '8'; 451 } 452 if (2 <= pos && src[pos - 2]) { 453 if (src[pos - 1]) { 454 return src[pos] ? '7' : '6'; 455 } 456 return src[pos] ? '5' : '4'; 457 } 458 if (1 <= pos && src[pos - 1]) { 459 return src[pos] ? '3' : '2'; 460 } 461 return src[pos] ? '1' : '0'; 462 } 463 464 /** 465 * Converts the 4 lsb of an int to a hexadecimal digit. 466 * 467 * <p> 468 * 0 returns '0' 469 * </p> 470 * <p> 471 * 1 returns '1' 472 * </p> 473 * <p> 474 * 10 returns 'A' and so on... 475 * </p> 476 * 477 * @param nibble the 4 bits to convert 478 * @return a hexadecimal digit representing the 4 lsb of {@code nibble} 479 * @throws IllegalArgumentException if {@code nibble < 0} or {@code nibble > 15} 480 */ intToHexDigit(final int nibble)481 public static char intToHexDigit(final int nibble) { 482 final char c = Character.forDigit(nibble, 16); 483 if (c == Character.MIN_VALUE) { 484 throw new IllegalArgumentException("nibble value not between 0 and 15: " + nibble); 485 } 486 return c; 487 } 488 489 /** 490 * Converts the 4 lsb of an int to a hexadecimal digit encoded using the Msb0 bit ordering. 491 * 492 * <p> 493 * 0 returns '0' 494 * </p> 495 * <p> 496 * 1 returns '8' 497 * </p> 498 * <p> 499 * 10 returns '5' and so on... 500 * </p> 501 * 502 * @param nibble the 4 bits to convert 503 * @return a hexadecimal digit representing the 4 lsb of {@code nibble} 504 * @throws IllegalArgumentException if {@code nibble < 0} or {@code nibble > 15} 505 */ intToHexDigitMsb0(final int nibble)506 public static char intToHexDigitMsb0(final int nibble) { 507 switch (nibble) { 508 case 0x0: 509 return '0'; 510 case 0x1: 511 return '8'; 512 case 0x2: 513 return '4'; 514 case 0x3: 515 return 'c'; 516 case 0x4: 517 return '2'; 518 case 0x5: 519 return 'a'; 520 case 0x6: 521 return '6'; 522 case 0x7: 523 return 'e'; 524 case 0x8: 525 return '1'; 526 case 0x9: 527 return '9'; 528 case 0xA: 529 return '5'; 530 case 0xB: 531 return 'd'; 532 case 0xC: 533 return '3'; 534 case 0xD: 535 return 'b'; 536 case 0xE: 537 return '7'; 538 case 0xF: 539 return 'f'; 540 default: 541 throw new IllegalArgumentException("nibble value not between 0 and 15: " + nibble); 542 } 543 } 544 545 /** 546 * Converts an array of int into a long using the default (little endian, Lsb0) byte and bit 547 * ordering. 548 * 549 * @param src the int array to convert 550 * @param srcPos the position in {@code src}, in int unit, from where to start the 551 * conversion 552 * @param dstInit initial value of the destination long 553 * @param dstPos the position of the lsb, in bits, in the result long 554 * @param nInts the number of ints to convert 555 * @return a long containing the selected bits 556 * @throws IllegalArgumentException if {@code (nInts-1)*32+dstPos >= 64} 557 * @throws NullPointerException if {@code src} is {@code null} 558 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nInts > src.length} 559 */ intArrayToLong(final int[] src, final int srcPos, final long dstInit, final int dstPos, final int nInts)560 public static long intArrayToLong(final int[] src, final int srcPos, final long dstInit, final int dstPos, 561 final int nInts) { 562 if (src.length == 0 && srcPos == 0 || 0 == nInts) { 563 return dstInit; 564 } 565 if ((nInts - 1) * 32 + dstPos >= 64) { 566 throw new IllegalArgumentException("(nInts-1)*32+dstPos is greater or equal to than 64"); 567 } 568 long out = dstInit; 569 for (int i = 0; i < nInts; i++) { 570 final int shift = i * 32 + dstPos; 571 final long bits = (0xffffffffL & src[i + srcPos]) << shift; 572 final long mask = 0xffffffffL << shift; 573 out = (out & ~mask) | bits; 574 } 575 return out; 576 } 577 578 /** 579 * Converts an array of short into a long using the default (little endian, Lsb0) byte and 580 * bit ordering. 581 * 582 * @param src the short array to convert 583 * @param srcPos the position in {@code src}, in short unit, from where to start the 584 * conversion 585 * @param dstInit initial value of the destination long 586 * @param dstPos the position of the lsb, in bits, in the result long 587 * @param nShorts the number of shorts to convert 588 * @return a long containing the selected bits 589 * @throws NullPointerException if {@code src} is {@code null} 590 * @throws IllegalArgumentException if {@code (nShorts-1)*16+dstPos >= 64} 591 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nShorts > src.length} 592 */ shortArrayToLong(final short[] src, final int srcPos, final long dstInit, final int dstPos, final int nShorts)593 public static long shortArrayToLong(final short[] src, final int srcPos, final long dstInit, final int dstPos, 594 final int nShorts) { 595 if (src.length == 0 && srcPos == 0 || 0 == nShorts) { 596 return dstInit; 597 } 598 if ((nShorts - 1) * 16 + dstPos >= 64) { 599 throw new IllegalArgumentException("(nShorts-1)*16+dstPos is greater or equal to than 64"); 600 } 601 long out = dstInit; 602 for (int i = 0; i < nShorts; i++) { 603 final int shift = i * 16 + dstPos; 604 final long bits = (0xffffL & src[i + srcPos]) << shift; 605 final long mask = 0xffffL << shift; 606 out = (out & ~mask) | bits; 607 } 608 return out; 609 } 610 611 /** 612 * Converts an array of short into an int using the default (little endian, Lsb0) byte and 613 * bit ordering. 614 * 615 * @param src the short array to convert 616 * @param srcPos the position in {@code src}, in short unit, from where to start the 617 * conversion 618 * @param dstInit initial value of the destination int 619 * @param dstPos the position of the lsb, in bits, in the result int 620 * @param nShorts the number of shorts to convert 621 * @return an int containing the selected bits 622 * @throws NullPointerException if {@code src} is {@code null} 623 * @throws IllegalArgumentException if {@code (nShorts-1)*16+dstPos >= 32} 624 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nShorts > src.length} 625 */ shortArrayToInt(final short[] src, final int srcPos, final int dstInit, final int dstPos, final int nShorts)626 public static int shortArrayToInt(final short[] src, final int srcPos, final int dstInit, final int dstPos, 627 final int nShorts) { 628 if (src.length == 0 && srcPos == 0 || 0 == nShorts) { 629 return dstInit; 630 } 631 if ((nShorts - 1) * 16 + dstPos >= 32) { 632 throw new IllegalArgumentException("(nShorts-1)*16+dstPos is greater or equal to than 32"); 633 } 634 int out = dstInit; 635 for (int i = 0; i < nShorts; i++) { 636 final int shift = i * 16 + dstPos; 637 final int bits = (0xffff & src[i + srcPos]) << shift; 638 final int mask = 0xffff << shift; 639 out = (out & ~mask) | bits; 640 } 641 return out; 642 } 643 644 /** 645 * Converts an array of byte into a long using the default (little endian, Lsb0) byte and 646 * bit ordering. 647 * 648 * @param src the byte array to convert 649 * @param srcPos the position in {@code src}, in byte unit, from where to start the 650 * conversion 651 * @param dstInit initial value of the destination long 652 * @param dstPos the position of the lsb, in bits, in the result long 653 * @param nBytes the number of bytes to convert 654 * @return a long containing the selected bits 655 * @throws NullPointerException if {@code src} is {@code null} 656 * @throws IllegalArgumentException if {@code (nBytes-1)*8+dstPos >= 64} 657 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBytes > src.length} 658 */ byteArrayToLong(final byte[] src, final int srcPos, final long dstInit, final int dstPos, final int nBytes)659 public static long byteArrayToLong(final byte[] src, final int srcPos, final long dstInit, final int dstPos, 660 final int nBytes) { 661 if (src.length == 0 && srcPos == 0 || 0 == nBytes) { 662 return dstInit; 663 } 664 if ((nBytes - 1) * 8 + dstPos >= 64) { 665 throw new IllegalArgumentException("(nBytes-1)*8+dstPos is greater or equal to than 64"); 666 } 667 long out = dstInit; 668 for (int i = 0; i < nBytes; i++) { 669 final int shift = i * 8 + dstPos; 670 final long bits = (0xffL & src[i + srcPos]) << shift; 671 final long mask = 0xffL << shift; 672 out = (out & ~mask) | bits; 673 } 674 return out; 675 } 676 677 /** 678 * Converts an array of byte into an int using the default (little endian, Lsb0) byte and bit 679 * ordering. 680 * 681 * @param src the byte array to convert 682 * @param srcPos the position in {@code src}, in byte unit, from where to start the 683 * conversion 684 * @param dstInit initial value of the destination int 685 * @param dstPos the position of the lsb, in bits, in the result int 686 * @param nBytes the number of bytes to convert 687 * @return an int containing the selected bits 688 * @throws NullPointerException if {@code src} is {@code null} 689 * @throws IllegalArgumentException if {@code (nBytes-1)*8+dstPos >= 32} 690 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBytes > src.length} 691 */ byteArrayToInt(final byte[] src, final int srcPos, final int dstInit, final int dstPos, final int nBytes)692 public static int byteArrayToInt(final byte[] src, final int srcPos, final int dstInit, final int dstPos, 693 final int nBytes) { 694 if (src.length == 0 && srcPos == 0 || 0 == nBytes) { 695 return dstInit; 696 } 697 if ((nBytes - 1) * 8 + dstPos >= 32) { 698 throw new IllegalArgumentException("(nBytes-1)*8+dstPos is greater or equal to than 32"); 699 } 700 int out = dstInit; 701 for (int i = 0; i < nBytes; i++) { 702 final int shift = i * 8 + dstPos; 703 final int bits = (0xff & src[i + srcPos]) << shift; 704 final int mask = 0xff << shift; 705 out = (out & ~mask) | bits; 706 } 707 return out; 708 } 709 710 /** 711 * Converts an array of byte into a short using the default (little endian, Lsb0) byte and 712 * bit ordering. 713 * 714 * @param src the byte array to convert 715 * @param srcPos the position in {@code src}, in byte unit, from where to start the 716 * conversion 717 * @param dstInit initial value of the destination short 718 * @param dstPos the position of the lsb, in bits, in the result short 719 * @param nBytes the number of bytes to convert 720 * @return a short containing the selected bits 721 * @throws NullPointerException if {@code src} is {@code null} 722 * @throws IllegalArgumentException if {@code (nBytes-1)*8+dstPos >= 16} 723 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBytes > src.length} 724 */ byteArrayToShort(final byte[] src, final int srcPos, final short dstInit, final int dstPos, final int nBytes)725 public static short byteArrayToShort(final byte[] src, final int srcPos, final short dstInit, final int dstPos, 726 final int nBytes) { 727 if (src.length == 0 && srcPos == 0 || 0 == nBytes) { 728 return dstInit; 729 } 730 if ((nBytes - 1) * 8 + dstPos >= 16) { 731 throw new IllegalArgumentException("(nBytes-1)*8+dstPos is greater or equal to than 16"); 732 } 733 short out = dstInit; 734 for (int i = 0; i < nBytes; i++) { 735 final int shift = i * 8 + dstPos; 736 final int bits = (0xff & src[i + srcPos]) << shift; 737 final int mask = 0xff << shift; 738 out = (short) ((out & ~mask) | bits); 739 } 740 return out; 741 } 742 743 /** 744 * Converts an array of Char into a long using the default (little endian, Lsb0) byte and 745 * bit ordering. 746 * 747 * @param src the hex string to convert 748 * @param srcPos the position in {@code src}, in Char unit, from where to start the 749 * conversion 750 * @param dstInit initial value of the destination long 751 * @param dstPos the position of the lsb, in bits, in the result long 752 * @param nHex the number of Chars to convert 753 * @return a long containing the selected bits 754 * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 64} 755 */ hexToLong(final String src, final int srcPos, final long dstInit, final int dstPos, final int nHex)756 public static long hexToLong(final String src, final int srcPos, final long dstInit, final int dstPos, 757 final int nHex) { 758 if (0 == nHex) { 759 return dstInit; 760 } 761 if ((nHex - 1) * 4 + dstPos >= 64) { 762 throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 64"); 763 } 764 long out = dstInit; 765 for (int i = 0; i < nHex; i++) { 766 final int shift = i * 4 + dstPos; 767 final long bits = (0xfL & hexDigitToInt(src.charAt(i + srcPos))) << shift; 768 final long mask = 0xfL << shift; 769 out = (out & ~mask) | bits; 770 } 771 return out; 772 } 773 774 /** 775 * Converts an array of Char into an int using the default (little endian, Lsb0) byte and bit 776 * ordering. 777 * 778 * @param src the hex string to convert 779 * @param srcPos the position in {@code src}, in Char unit, from where to start the 780 * conversion 781 * @param dstInit initial value of the destination int 782 * @param dstPos the position of the lsb, in bits, in the result int 783 * @param nHex the number of Chars to convert 784 * @return an int containing the selected bits 785 * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 32} 786 */ hexToInt(final String src, final int srcPos, final int dstInit, final int dstPos, final int nHex)787 public static int hexToInt(final String src, final int srcPos, final int dstInit, final int dstPos, final int nHex) { 788 if (0 == nHex) { 789 return dstInit; 790 } 791 if ((nHex - 1) * 4 + dstPos >= 32) { 792 throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 32"); 793 } 794 int out = dstInit; 795 for (int i = 0; i < nHex; i++) { 796 final int shift = i * 4 + dstPos; 797 final int bits = (0xf & hexDigitToInt(src.charAt(i + srcPos))) << shift; 798 final int mask = 0xf << shift; 799 out = (out & ~mask) | bits; 800 } 801 return out; 802 } 803 804 /** 805 * Converts an array of Char into a short using the default (little endian, Lsb0) byte and 806 * bit ordering. 807 * 808 * @param src the hex string to convert 809 * @param srcPos the position in {@code src}, in Char unit, from where to start the 810 * conversion 811 * @param dstInit initial value of the destination short 812 * @param dstPos the position of the lsb, in bits, in the result short 813 * @param nHex the number of Chars to convert 814 * @return a short containing the selected bits 815 * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 16} 816 */ hexToShort(final String src, final int srcPos, final short dstInit, final int dstPos, final int nHex)817 public static short hexToShort(final String src, final int srcPos, final short dstInit, final int dstPos, 818 final int nHex) { 819 if (0 == nHex) { 820 return dstInit; 821 } 822 if ((nHex - 1) * 4 + dstPos >= 16) { 823 throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 16"); 824 } 825 short out = dstInit; 826 for (int i = 0; i < nHex; i++) { 827 final int shift = i * 4 + dstPos; 828 final int bits = (0xf & hexDigitToInt(src.charAt(i + srcPos))) << shift; 829 final int mask = 0xf << shift; 830 out = (short) ((out & ~mask) | bits); 831 } 832 return out; 833 } 834 835 /** 836 * Converts an array of Char into a byte using the default (little endian, Lsb0) byte and 837 * bit ordering. 838 * 839 * @param src the hex string to convert 840 * @param srcPos the position in {@code src}, in Char unit, from where to start the 841 * conversion 842 * @param dstInit initial value of the destination byte 843 * @param dstPos the position of the lsb, in bits, in the result byte 844 * @param nHex the number of Chars to convert 845 * @return a byte containing the selected bits 846 * @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 8} 847 */ hexToByte(final String src, final int srcPos, final byte dstInit, final int dstPos, final int nHex)848 public static byte hexToByte(final String src, final int srcPos, final byte dstInit, final int dstPos, 849 final int nHex) { 850 if (0 == nHex) { 851 return dstInit; 852 } 853 if ((nHex - 1) * 4 + dstPos >= 8) { 854 throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 8"); 855 } 856 byte out = dstInit; 857 for (int i = 0; i < nHex; i++) { 858 final int shift = i * 4 + dstPos; 859 final int bits = (0xf & hexDigitToInt(src.charAt(i + srcPos))) << shift; 860 final int mask = 0xf << shift; 861 out = (byte) ((out & ~mask) | bits); 862 } 863 return out; 864 } 865 866 /** 867 * Converts binary (represented as boolean array) into a long using the default (little 868 * endian, Lsb0) byte and bit ordering. 869 * 870 * @param src the binary to convert 871 * @param srcPos the position in {@code src}, in boolean unit, from where to start the 872 * conversion 873 * @param dstInit initial value of the destination long 874 * @param dstPos the position of the lsb, in bits, in the result long 875 * @param nBools the number of booleans to convert 876 * @return a long containing the selected bits 877 * @throws NullPointerException if {@code src} is {@code null} 878 * @throws IllegalArgumentException if {@code nBools-1+dstPos >= 64} 879 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBools > src.length} 880 */ binaryToLong(final boolean[] src, final int srcPos, final long dstInit, final int dstPos, final int nBools)881 public static long binaryToLong(final boolean[] src, final int srcPos, final long dstInit, final int dstPos, 882 final int nBools) { 883 if (src.length == 0 && srcPos == 0 || 0 == nBools) { 884 return dstInit; 885 } 886 if (nBools - 1 + dstPos >= 64) { 887 throw new IllegalArgumentException("nBools-1+dstPos is greater or equal to than 64"); 888 } 889 long out = dstInit; 890 for (int i = 0; i < nBools; i++) { 891 final int shift = i + dstPos; 892 final long bits = (src[i + srcPos] ? 1L : 0) << shift; 893 final long mask = 0x1L << shift; 894 out = (out & ~mask) | bits; 895 } 896 return out; 897 } 898 899 /** 900 * Converts binary (represented as boolean array) into an int using the default (little 901 * endian, Lsb0) byte and bit ordering. 902 * 903 * @param src the binary to convert 904 * @param srcPos the position in {@code src}, in boolean unit, from where to start the 905 * conversion 906 * @param dstInit initial value of the destination int 907 * @param dstPos the position of the lsb, in bits, in the result int 908 * @param nBools the number of booleans to convert 909 * @return an int containing the selected bits 910 * @throws NullPointerException if {@code src} is {@code null} 911 * @throws IllegalArgumentException if {@code nBools-1+dstPos >= 32} 912 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBools > src.length} 913 */ binaryToInt(final boolean[] src, final int srcPos, final int dstInit, final int dstPos, final int nBools)914 public static int binaryToInt(final boolean[] src, final int srcPos, final int dstInit, final int dstPos, 915 final int nBools) { 916 if (src.length == 0 && srcPos == 0 || 0 == nBools) { 917 return dstInit; 918 } 919 if (nBools - 1 + dstPos >= 32) { 920 throw new IllegalArgumentException("nBools-1+dstPos is greater or equal to than 32"); 921 } 922 int out = dstInit; 923 for (int i = 0; i < nBools; i++) { 924 final int shift = i + dstPos; 925 final int bits = (src[i + srcPos] ? 1 : 0) << shift; 926 final int mask = 0x1 << shift; 927 out = (out & ~mask) | bits; 928 } 929 return out; 930 } 931 932 /** 933 * Converts binary (represented as boolean array) into a short using the default (little 934 * endian, Lsb0) byte and bit ordering. 935 * 936 * @param src the binary to convert 937 * @param srcPos the position in {@code src}, in boolean unit, from where to start the 938 * conversion 939 * @param dstInit initial value of the destination short 940 * @param dstPos the position of the lsb, in bits, in the result short 941 * @param nBools the number of booleans to convert 942 * @return a short containing the selected bits 943 * @throws NullPointerException if {@code src} is {@code null} 944 * @throws IllegalArgumentException if {@code nBools-1+dstPos >= 16} 945 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBools > src.length} 946 */ binaryToShort(final boolean[] src, final int srcPos, final short dstInit, final int dstPos, final int nBools)947 public static short binaryToShort(final boolean[] src, final int srcPos, final short dstInit, final int dstPos, 948 final int nBools) { 949 if (src.length == 0 && srcPos == 0 || 0 == nBools) { 950 return dstInit; 951 } 952 if (nBools - 1 + dstPos >= 16) { 953 throw new IllegalArgumentException("nBools-1+dstPos is greater or equal to than 16"); 954 } 955 short out = dstInit; 956 for (int i = 0; i < nBools; i++) { 957 final int shift = i + dstPos; 958 final int bits = (src[i + srcPos] ? 1 : 0) << shift; 959 final int mask = 0x1 << shift; 960 out = (short) ((out & ~mask) | bits); 961 } 962 return out; 963 } 964 965 /** 966 * Converts binary (represented as boolean array) into a byte using the default (little 967 * endian, Lsb0) byte and bit ordering. 968 * 969 * @param src the binary to convert 970 * @param srcPos the position in {@code src}, in boolean unit, from where to start the 971 * conversion 972 * @param dstInit initial value of the destination byte 973 * @param dstPos the position of the lsb, in bits, in the result byte 974 * @param nBools the number of booleans to convert 975 * @return a byte containing the selected bits 976 * @throws NullPointerException if {@code src} is {@code null} 977 * @throws IllegalArgumentException if {@code nBools-1+dstPos >= 8} 978 * @throws ArrayIndexOutOfBoundsException if {@code srcPos + nBools > src.length} 979 */ binaryToByte(final boolean[] src, final int srcPos, final byte dstInit, final int dstPos, final int nBools)980 public static byte binaryToByte(final boolean[] src, final int srcPos, final byte dstInit, final int dstPos, 981 final int nBools) { 982 if (src.length == 0 && srcPos == 0 || 0 == nBools) { 983 return dstInit; 984 } 985 if (nBools - 1 + dstPos >= 8) { 986 throw new IllegalArgumentException("nBools-1+dstPos is greater or equal to than 8"); 987 } 988 byte out = dstInit; 989 for (int i = 0; i < nBools; i++) { 990 final int shift = i + dstPos; 991 final int bits = (src[i + srcPos] ? 1 : 0) << shift; 992 final int mask = 0x1 << shift; 993 out = (byte) ((out & ~mask) | bits); 994 } 995 return out; 996 } 997 998 /** 999 * Converts a long into an array of int using the default (little endian, Lsb0) byte and bit 1000 * ordering. 1001 * 1002 * @param src the long to convert 1003 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1004 * @param dst the destination array 1005 * @param dstPos the position in {@code dst} where to copy the result 1006 * @param nInts the number of ints to copy to {@code dst}, must be smaller or equal to the 1007 * width of the input (from srcPos to msb) 1008 * @return {@code dst} 1009 * @throws NullPointerException if {@code dst} is {@code null} and {@code nInts > 0} 1010 * @throws IllegalArgumentException if {@code (nInts-1)*32+srcPos >= 64} 1011 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nInts > dst.length} 1012 */ longToIntArray(final long src, final int srcPos, final int[] dst, final int dstPos, final int nInts)1013 public static int[] longToIntArray(final long src, final int srcPos, final int[] dst, final int dstPos, 1014 final int nInts) { 1015 if (0 == nInts) { 1016 return dst; 1017 } 1018 if ((nInts - 1) * 32 + srcPos >= 64) { 1019 throw new IllegalArgumentException("(nInts-1)*32+srcPos is greater or equal to than 64"); 1020 } 1021 for (int i = 0; i < nInts; i++) { 1022 final int shift = i * 32 + srcPos; 1023 dst[dstPos + i] = (int) (0xffffffff & (src >> shift)); 1024 } 1025 return dst; 1026 } 1027 1028 /** 1029 * Converts a long into an array of short using the default (little endian, Lsb0) byte and 1030 * bit ordering. 1031 * 1032 * @param src the long to convert 1033 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1034 * @param dst the destination array 1035 * @param dstPos the position in {@code dst} where to copy the result 1036 * @param nShorts the number of shorts to copy to {@code dst}, must be smaller or equal to 1037 * the width of the input (from srcPos to msb) 1038 * @return {@code dst} 1039 * @throws NullPointerException if {@code dst} is {@code null} 1040 * @throws IllegalArgumentException if {@code (nShorts-1)*16+srcPos >= 64} 1041 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nShorts > dst.length} 1042 */ longToShortArray(final long src, final int srcPos, final short[] dst, final int dstPos, final int nShorts)1043 public static short[] longToShortArray(final long src, final int srcPos, final short[] dst, final int dstPos, 1044 final int nShorts) { 1045 if (0 == nShorts) { 1046 return dst; 1047 } 1048 if ((nShorts - 1) * 16 + srcPos >= 64) { 1049 throw new IllegalArgumentException("(nShorts-1)*16+srcPos is greater or equal to than 64"); 1050 } 1051 for (int i = 0; i < nShorts; i++) { 1052 final int shift = i * 16 + srcPos; 1053 dst[dstPos + i] = (short) (0xffff & (src >> shift)); 1054 } 1055 return dst; 1056 } 1057 1058 /** 1059 * Converts an int into an array of short using the default (little endian, Lsb0) byte and 1060 * bit ordering. 1061 * 1062 * @param src the int to convert 1063 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1064 * @param dst the destination array 1065 * @param dstPos the position in {@code dst} where to copy the result 1066 * @param nShorts the number of shorts to copy to {@code dst}, must be smaller or equal to 1067 * the width of the input (from srcPos to msb) 1068 * @return {@code dst} 1069 * @throws NullPointerException if {@code dst} is {@code null} 1070 * @throws IllegalArgumentException if {@code (nShorts-1)*16+srcPos >= 32} 1071 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nShorts > dst.length} 1072 */ intToShortArray(final int src, final int srcPos, final short[] dst, final int dstPos, final int nShorts)1073 public static short[] intToShortArray(final int src, final int srcPos, final short[] dst, final int dstPos, 1074 final int nShorts) { 1075 if (0 == nShorts) { 1076 return dst; 1077 } 1078 if ((nShorts - 1) * 16 + srcPos >= 32) { 1079 throw new IllegalArgumentException("(nShorts-1)*16+srcPos is greater or equal to than 32"); 1080 } 1081 for (int i = 0; i < nShorts; i++) { 1082 final int shift = i * 16 + srcPos; 1083 dst[dstPos + i] = (short) (0xffff & (src >> shift)); 1084 } 1085 return dst; 1086 } 1087 1088 /** 1089 * Converts a long into an array of byte using the default (little endian, Lsb0) byte and 1090 * bit ordering. 1091 * 1092 * @param src the long to convert 1093 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1094 * @param dst the destination array 1095 * @param dstPos the position in {@code dst} where to copy the result 1096 * @param nBytes the number of bytes to copy to {@code dst}, must be smaller or equal to the 1097 * width of the input (from srcPos to msb) 1098 * @return {@code dst} 1099 * @throws NullPointerException if {@code dst} is {@code null} 1100 * @throws IllegalArgumentException if {@code (nBytes-1)*8+srcPos >= 64} 1101 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBytes > dst.length} 1102 */ longToByteArray(final long src, final int srcPos, final byte[] dst, final int dstPos, final int nBytes)1103 public static byte[] longToByteArray(final long src, final int srcPos, final byte[] dst, final int dstPos, 1104 final int nBytes) { 1105 if (0 == nBytes) { 1106 return dst; 1107 } 1108 if ((nBytes - 1) * 8 + srcPos >= 64) { 1109 throw new IllegalArgumentException("(nBytes-1)*8+srcPos is greater or equal to than 64"); 1110 } 1111 for (int i = 0; i < nBytes; i++) { 1112 final int shift = i * 8 + srcPos; 1113 dst[dstPos + i] = (byte) (0xff & (src >> shift)); 1114 } 1115 return dst; 1116 } 1117 1118 /** 1119 * Converts an int into an array of byte using the default (little endian, Lsb0) byte and bit 1120 * ordering. 1121 * 1122 * @param src the int to convert 1123 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1124 * @param dst the destination array 1125 * @param dstPos the position in {@code dst} where to copy the result 1126 * @param nBytes the number of bytes to copy to {@code dst}, must be smaller or equal to the 1127 * width of the input (from srcPos to msb) 1128 * @return {@code dst} 1129 * @throws NullPointerException if {@code dst} is {@code null} 1130 * @throws IllegalArgumentException if {@code (nBytes-1)*8+srcPos >= 32} 1131 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBytes > dst.length} 1132 */ intToByteArray(final int src, final int srcPos, final byte[] dst, final int dstPos, final int nBytes)1133 public static byte[] intToByteArray(final int src, final int srcPos, final byte[] dst, final int dstPos, 1134 final int nBytes) { 1135 if (0 == nBytes) { 1136 return dst; 1137 } 1138 if ((nBytes - 1) * 8 + srcPos >= 32) { 1139 throw new IllegalArgumentException("(nBytes-1)*8+srcPos is greater or equal to than 32"); 1140 } 1141 for (int i = 0; i < nBytes; i++) { 1142 final int shift = i * 8 + srcPos; 1143 dst[dstPos + i] = (byte) (0xff & (src >> shift)); 1144 } 1145 return dst; 1146 } 1147 1148 /** 1149 * Converts a short into an array of byte using the default (little endian, Lsb0) byte and 1150 * bit ordering. 1151 * 1152 * @param src the short to convert 1153 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1154 * @param dst the destination array 1155 * @param dstPos the position in {@code dst} where to copy the result 1156 * @param nBytes the number of bytes to copy to {@code dst}, must be smaller or equal to the 1157 * width of the input (from srcPos to msb) 1158 * @return {@code dst} 1159 * @throws NullPointerException if {@code dst} is {@code null} 1160 * @throws IllegalArgumentException if {@code (nBytes-1)*8+srcPos >= 16} 1161 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBytes > dst.length} 1162 */ shortToByteArray(final short src, final int srcPos, final byte[] dst, final int dstPos, final int nBytes)1163 public static byte[] shortToByteArray(final short src, final int srcPos, final byte[] dst, final int dstPos, 1164 final int nBytes) { 1165 if (0 == nBytes) { 1166 return dst; 1167 } 1168 if ((nBytes - 1) * 8 + srcPos >= 16) { 1169 throw new IllegalArgumentException("(nBytes-1)*8+srcPos is greater or equal to than 16"); 1170 } 1171 for (int i = 0; i < nBytes; i++) { 1172 final int shift = i * 8 + srcPos; 1173 dst[dstPos + i] = (byte) (0xff & (src >> shift)); 1174 } 1175 return dst; 1176 } 1177 1178 /** 1179 * Converts a long into an array of Char using the default (little endian, Lsb0) byte and 1180 * bit ordering. 1181 * 1182 * @param src the long to convert 1183 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1184 * @param dstInit the initial value for the result String 1185 * @param dstPos the position in {@code dst} where to copy the result 1186 * @param nHexs the number of Chars to copy to {@code dst}, must be smaller or equal to the 1187 * width of the input (from srcPos to msb) 1188 * @return {@code dst} 1189 * @throws IllegalArgumentException if {@code (nHexs-1)*4+srcPos >= 64} 1190 * @throws StringIndexOutOfBoundsException if {@code dst.init.length() < dstPos} 1191 */ longToHex(final long src, final int srcPos, final String dstInit, final int dstPos, final int nHexs)1192 public static String longToHex(final long src, final int srcPos, final String dstInit, final int dstPos, 1193 final int nHexs) { 1194 if (0 == nHexs) { 1195 return dstInit; 1196 } 1197 if ((nHexs - 1) * 4 + srcPos >= 64) { 1198 throw new IllegalArgumentException("(nHexs-1)*4+srcPos is greater or equal to than 64"); 1199 } 1200 final StringBuilder sb = new StringBuilder(dstInit); 1201 int append = sb.length(); 1202 for (int i = 0; i < nHexs; i++) { 1203 final int shift = i * 4 + srcPos; 1204 final int bits = (int) (0xF & (src >> shift)); 1205 if (dstPos + i == append) { 1206 ++append; 1207 sb.append(intToHexDigit(bits)); 1208 } else { 1209 sb.setCharAt(dstPos + i, intToHexDigit(bits)); 1210 } 1211 } 1212 return sb.toString(); 1213 } 1214 1215 /** 1216 * Converts an int into an array of Char using the default (little endian, Lsb0) byte and bit 1217 * ordering. 1218 * 1219 * @param src the int to convert 1220 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1221 * @param dstInit the initial value for the result String 1222 * @param dstPos the position in {@code dst} where to copy the result 1223 * @param nHexs the number of Chars to copy to {@code dst}, must be smaller or equal to the 1224 * width of the input (from srcPos to msb) 1225 * @return {@code dst} 1226 * @throws IllegalArgumentException if {@code (nHexs-1)*4+srcPos >= 32} 1227 * @throws StringIndexOutOfBoundsException if {@code dst.init.length() < dstPos} 1228 */ intToHex(final int src, final int srcPos, final String dstInit, final int dstPos, final int nHexs)1229 public static String intToHex(final int src, final int srcPos, final String dstInit, final int dstPos, 1230 final int nHexs) { 1231 if (0 == nHexs) { 1232 return dstInit; 1233 } 1234 if ((nHexs - 1) * 4 + srcPos >= 32) { 1235 throw new IllegalArgumentException("(nHexs-1)*4+srcPos is greater or equal to than 32"); 1236 } 1237 final StringBuilder sb = new StringBuilder(dstInit); 1238 int append = sb.length(); 1239 for (int i = 0; i < nHexs; i++) { 1240 final int shift = i * 4 + srcPos; 1241 final int bits = 0xF & (src >> shift); 1242 if (dstPos + i == append) { 1243 ++append; 1244 sb.append(intToHexDigit(bits)); 1245 } else { 1246 sb.setCharAt(dstPos + i, intToHexDigit(bits)); 1247 } 1248 } 1249 return sb.toString(); 1250 } 1251 1252 /** 1253 * Converts a short into an array of Char using the default (little endian, Lsb0) byte and 1254 * bit ordering. 1255 * 1256 * @param src the short to convert 1257 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1258 * @param dstInit the initial value for the result String 1259 * @param dstPos the position in {@code dst} where to copy the result 1260 * @param nHexs the number of Chars to copy to {@code dst}, must be smaller or equal to the 1261 * width of the input (from srcPos to msb) 1262 * @return {@code dst} 1263 * @throws IllegalArgumentException if {@code (nHexs-1)*4+srcPos >= 16} 1264 * @throws StringIndexOutOfBoundsException if {@code dst.init.length() < dstPos} 1265 */ shortToHex(final short src, final int srcPos, final String dstInit, final int dstPos, final int nHexs)1266 public static String shortToHex(final short src, final int srcPos, final String dstInit, final int dstPos, 1267 final int nHexs) { 1268 if (0 == nHexs) { 1269 return dstInit; 1270 } 1271 if ((nHexs - 1) * 4 + srcPos >= 16) { 1272 throw new IllegalArgumentException("(nHexs-1)*4+srcPos is greater or equal to than 16"); 1273 } 1274 final StringBuilder sb = new StringBuilder(dstInit); 1275 int append = sb.length(); 1276 for (int i = 0; i < nHexs; i++) { 1277 final int shift = i * 4 + srcPos; 1278 final int bits = 0xF & (src >> shift); 1279 if (dstPos + i == append) { 1280 ++append; 1281 sb.append(intToHexDigit(bits)); 1282 } else { 1283 sb.setCharAt(dstPos + i, intToHexDigit(bits)); 1284 } 1285 } 1286 return sb.toString(); 1287 } 1288 1289 /** 1290 * Converts a byte into an array of Char using the default (little endian, Lsb0) byte and 1291 * bit ordering. 1292 * 1293 * @param src the byte to convert 1294 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1295 * @param dstInit the initial value for the result String 1296 * @param dstPos the position in {@code dst} where to copy the result 1297 * @param nHexs the number of Chars to copy to {@code dst}, must be smaller or equal to the 1298 * width of the input (from srcPos to msb) 1299 * @return {@code dst} 1300 * @throws IllegalArgumentException if {@code (nHexs-1)*4+srcPos >= 8} 1301 * @throws StringIndexOutOfBoundsException if {@code dst.init.length() < dstPos} 1302 */ byteToHex(final byte src, final int srcPos, final String dstInit, final int dstPos, final int nHexs)1303 public static String byteToHex(final byte src, final int srcPos, final String dstInit, final int dstPos, 1304 final int nHexs) { 1305 if (0 == nHexs) { 1306 return dstInit; 1307 } 1308 if ((nHexs - 1) * 4 + srcPos >= 8) { 1309 throw new IllegalArgumentException("(nHexs-1)*4+srcPos is greater or equal to than 8"); 1310 } 1311 final StringBuilder sb = new StringBuilder(dstInit); 1312 int append = sb.length(); 1313 for (int i = 0; i < nHexs; i++) { 1314 final int shift = i * 4 + srcPos; 1315 final int bits = 0xF & (src >> shift); 1316 if (dstPos + i == append) { 1317 ++append; 1318 sb.append(intToHexDigit(bits)); 1319 } else { 1320 sb.setCharAt(dstPos + i, intToHexDigit(bits)); 1321 } 1322 } 1323 return sb.toString(); 1324 } 1325 1326 /** 1327 * Converts a long into an array of boolean using the default (little endian, Lsb0) byte and 1328 * bit ordering. 1329 * 1330 * @param src the long to convert 1331 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1332 * @param dst the destination array 1333 * @param dstPos the position in {@code dst} where to copy the result 1334 * @param nBools the number of booleans to copy to {@code dst}, must be smaller or equal to 1335 * the width of the input (from srcPos to msb) 1336 * @return {@code dst} 1337 * @throws NullPointerException if {@code dst} is {@code null} 1338 * @throws IllegalArgumentException if {@code nBools-1+srcPos >= 64} 1339 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBools > dst.length} 1340 */ longToBinary(final long src, final int srcPos, final boolean[] dst, final int dstPos, final int nBools)1341 public static boolean[] longToBinary(final long src, final int srcPos, final boolean[] dst, final int dstPos, 1342 final int nBools) { 1343 if (0 == nBools) { 1344 return dst; 1345 } 1346 if (nBools - 1 + srcPos >= 64) { 1347 throw new IllegalArgumentException("nBools-1+srcPos is greater or equal to than 64"); 1348 } 1349 for (int i = 0; i < nBools; i++) { 1350 final int shift = i + srcPos; 1351 dst[dstPos + i] = (0x1 & (src >> shift)) != 0; 1352 } 1353 return dst; 1354 } 1355 1356 /** 1357 * Converts an int into an array of boolean using the default (little endian, Lsb0) byte and 1358 * bit ordering. 1359 * 1360 * @param src the int to convert 1361 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1362 * @param dst the destination array 1363 * @param dstPos the position in {@code dst} where to copy the result 1364 * @param nBools the number of booleans to copy to {@code dst}, must be smaller or equal to 1365 * the width of the input (from srcPos to msb) 1366 * @return {@code dst} 1367 * @throws NullPointerException if {@code dst} is {@code null} 1368 * @throws IllegalArgumentException if {@code nBools-1+srcPos >= 32} 1369 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBools > dst.length} 1370 */ intToBinary(final int src, final int srcPos, final boolean[] dst, final int dstPos, final int nBools)1371 public static boolean[] intToBinary(final int src, final int srcPos, final boolean[] dst, final int dstPos, 1372 final int nBools) { 1373 if (0 == nBools) { 1374 return dst; 1375 } 1376 if (nBools - 1 + srcPos >= 32) { 1377 throw new IllegalArgumentException("nBools-1+srcPos is greater or equal to than 32"); 1378 } 1379 for (int i = 0; i < nBools; i++) { 1380 final int shift = i + srcPos; 1381 dst[dstPos + i] = (0x1 & (src >> shift)) != 0; 1382 } 1383 return dst; 1384 } 1385 1386 /** 1387 * Converts a short into an array of boolean using the default (little endian, Lsb0) byte 1388 * and bit ordering. 1389 * 1390 * @param src the short to convert 1391 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1392 * @param dst the destination array 1393 * @param dstPos the position in {@code dst} where to copy the result 1394 * @param nBools the number of booleans to copy to {@code dst}, must be smaller or equal to 1395 * the width of the input (from srcPos to msb) 1396 * @return {@code dst} 1397 * @throws NullPointerException if {@code dst} is {@code null} 1398 * @throws IllegalArgumentException if {@code nBools-1+srcPos >= 16} 1399 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBools > dst.length} 1400 */ shortToBinary(final short src, final int srcPos, final boolean[] dst, final int dstPos, final int nBools)1401 public static boolean[] shortToBinary(final short src, final int srcPos, final boolean[] dst, final int dstPos, 1402 final int nBools) { 1403 if (0 == nBools) { 1404 return dst; 1405 } 1406 if (nBools - 1 + srcPos >= 16) { 1407 throw new IllegalArgumentException("nBools-1+srcPos is greater or equal to than 16"); 1408 } 1409 assert (nBools - 1) < 16 - srcPos; 1410 for (int i = 0; i < nBools; i++) { 1411 final int shift = i + srcPos; 1412 dst[dstPos + i] = (0x1 & (src >> shift)) != 0; 1413 } 1414 return dst; 1415 } 1416 1417 /** 1418 * Converts a byte into an array of boolean using the default (little endian, Lsb0) byte and 1419 * bit ordering. 1420 * 1421 * @param src the byte to convert 1422 * @param srcPos the position in {@code src}, in bits, from where to start the conversion 1423 * @param dst the destination array 1424 * @param dstPos the position in {@code dst} where to copy the result 1425 * @param nBools the number of booleans to copy to {@code dst}, must be smaller or equal to 1426 * the width of the input (from srcPos to msb) 1427 * @return {@code dst} 1428 * @throws NullPointerException if {@code dst} is {@code null} 1429 * @throws IllegalArgumentException if {@code nBools-1+srcPos >= 8} 1430 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBools > dst.length} 1431 */ byteToBinary(final byte src, final int srcPos, final boolean[] dst, final int dstPos, final int nBools)1432 public static boolean[] byteToBinary(final byte src, final int srcPos, final boolean[] dst, final int dstPos, 1433 final int nBools) { 1434 if (0 == nBools) { 1435 return dst; 1436 } 1437 if (nBools - 1 + srcPos >= 8) { 1438 throw new IllegalArgumentException("nBools-1+srcPos is greater or equal to than 8"); 1439 } 1440 for (int i = 0; i < nBools; i++) { 1441 final int shift = i + srcPos; 1442 dst[dstPos + i] = (0x1 & (src >> shift)) != 0; 1443 } 1444 return dst; 1445 } 1446 1447 /** 1448 * Converts UUID into an array of byte using the default (little endian, Lsb0) byte and bit 1449 * ordering. 1450 * 1451 * @param src the UUID to convert 1452 * @param dst the destination array 1453 * @param dstPos the position in {@code dst} where to copy the result 1454 * @param nBytes the number of bytes to copy to {@code dst}, must be smaller or equal to the 1455 * width of the input (from srcPos to msb) 1456 * @return {@code dst} 1457 * @throws NullPointerException if {@code dst} is {@code null} 1458 * @throws IllegalArgumentException if {@code nBytes > 16} 1459 * @throws ArrayIndexOutOfBoundsException if {@code dstPos + nBytes > dst.length} 1460 */ uuidToByteArray(final UUID src, final byte[] dst, final int dstPos, final int nBytes)1461 public static byte[] uuidToByteArray(final UUID src, final byte[] dst, final int dstPos, final int nBytes) { 1462 if (0 == nBytes) { 1463 return dst; 1464 } 1465 if (nBytes > 16) { 1466 throw new IllegalArgumentException("nBytes is greater than 16"); 1467 } 1468 longToByteArray(src.getMostSignificantBits(), 0, dst, dstPos, Math.min(nBytes, 8)); 1469 if (nBytes >= 8) { 1470 longToByteArray(src.getLeastSignificantBits(), 0, dst, dstPos + 8, nBytes - 8); 1471 } 1472 return dst; 1473 } 1474 1475 /** 1476 * Converts bytes from an array into a UUID using the default (little endian, Lsb0) byte and 1477 * bit ordering. 1478 * 1479 * @param src the byte array to convert 1480 * @param srcPos the position in {@code src} where to copy the result from 1481 * @return a UUID 1482 * @throws NullPointerException if {@code src} is {@code null} 1483 * @throws IllegalArgumentException if array does not contain at least 16 bytes beginning 1484 * with {@code srcPos} 1485 */ byteArrayToUuid(final byte[] src, final int srcPos)1486 public static UUID byteArrayToUuid(final byte[] src, final int srcPos) { 1487 if (src.length - srcPos < 16) { 1488 throw new IllegalArgumentException("Need at least 16 bytes for UUID"); 1489 } 1490 return new UUID(byteArrayToLong(src, srcPos, 0, 0, 8), byteArrayToLong(src, srcPos + 8, 0, 0, 8)); 1491 } 1492 } 1493