001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3; 018 019import java.util.UUID; 020 021 022/** 023 * Static methods to convert a type into another, with endianness and bit ordering awareness. 024 * 025 * <p> 026 * The methods names follow a naming rule:<br> 027 * {@code <source type>[source endianness][source bit ordering]To<destination type>[destination endianness][destination bit ordering]} 028 * </p> 029 * <p> 030 * Source/destination type fields is one of the following: 031 * </p> 032 * <ul> 033 * <li>binary: an array of booleans</li> 034 * <li>byte or byteArray</li> 035 * <li>int or intArray</li> 036 * <li>long or longArray</li> 037 * <li>hex: a String containing hexadecimal digits (lowercase in destination)</li> 038 * <li>hexDigit: a Char containing a hexadecimal digit (lowercase in destination)</li> 039 * <li>uuid</li> 040 * </ul> 041 * <p> 042 * Endianness field: little endian is the default, in this case the field is absent. In case of 043 * big endian, the field is "Be".<br> Bit ordering: Lsb0 is the default, in this case the field 044 * is absent. In case of Msb0, the field is "Msb0". 045 * </p> 046 * <p> 047 * Example: intBeMsb0ToHex convert an int with big endian byte order and Msb0 bit order into its 048 * hexadecimal string representation 049 * </p> 050 * <p> 051 * Most of the methods provide only default encoding for destination, this limits the number of 052 * ways to do one thing. Unless you are dealing with data from/to outside of the JVM platform, 053 * you should not need to use "Be" and "Msb0" methods. 054 * </p> 055 * <p> 056 * Development status: work on going, only a part of the little endian, Lsb0 methods implemented 057 * so far. 058 * </p> 059 * 060 * @since 3.2 061 */ 062 063public class Conversion { 064 065 private static final boolean[] TTTT = {true, true, true, true}; 066 private static final boolean[] FTTT = {false, true, true, true}; 067 private static final boolean[] TFTT = {true, false, true, true}; 068 private static final boolean[] FFTT = {false, false, true, true}; 069 private static final boolean[] TTFT = {true, true, false, true}; 070 private static final boolean[] FTFT = {false, true, false, true}; 071 private static final boolean[] TFFT = {true, false, false, true}; 072 private static final boolean[] FFFT = {false, false, false, true}; 073 private static final boolean[] TTTF = {true, true, true, false}; 074 private static final boolean[] FTTF = {false, true, true, false}; 075 private static final boolean[] TFTF = {true, false, true, false}; 076 private static final boolean[] FFTF = {false, false, true, false}; 077 private static final boolean[] TTFF = {true, true, false, false}; 078 private static final boolean[] FTFF = {false, true, false, false}; 079 private static final boolean[] TFFF = {true, false, false, false}; 080 private static final boolean[] FFFF = {false, false, false, false}; 081 082 /** 083 * Converts a hexadecimal digit into an int using the default (Lsb0) bit ordering. 084 * 085 * <p> 086 * '1' is converted to 1 087 * </p> 088 * 089 * @param hexDigit the hexadecimal digit to convert 090 * @return an int equals to {@code hexDigit} 091 * @throws IllegalArgumentException if {@code hexDigit} is not a hexadecimal digit 092 */ 093 public static int hexDigitToInt(final char hexDigit) { 094 final int digit = Character.digit(hexDigit, 16); 095 if (digit < 0) { 096 throw new IllegalArgumentException("Cannot interpret '" + hexDigit + "' as a hexadecimal digit"); 097 } 098 return digit; 099 } 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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}