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