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