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