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