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