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