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