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