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