1package org.bouncycastle.util;
2
3/**
4 * Utility methods for converting byte arrays into ints and longs, and back again.
5 */
6public abstract class Pack
7{
8    public static short bigEndianToShort(byte[] bs, int off)
9    {
10        int n = (bs[  off] & 0xff) << 8;
11        n |= (bs[++off] & 0xff);
12        return (short)n;
13    }
14
15    public static int bigEndianToInt(byte[] bs, int off)
16    {
17        int n = bs[  off] << 24;
18        n |= (bs[++off] & 0xff) << 16;
19        n |= (bs[++off] & 0xff) << 8;
20        n |= (bs[++off] & 0xff);
21        return n;
22    }
23
24    public static void bigEndianToInt(byte[] bs, int off, int[] ns)
25    {
26        for (int i = 0; i < ns.length; ++i)
27        {
28            ns[i] = bigEndianToInt(bs, off);
29            off += 4;
30        }
31    }
32
33    public static byte[] intToBigEndian(int n)
34    {
35        byte[] bs = new byte[4];
36        intToBigEndian(n, bs, 0);
37        return bs;
38    }
39
40    public static void intToBigEndian(int n, byte[] bs, int off)
41    {
42        bs[  off] = (byte)(n >>> 24);
43        bs[++off] = (byte)(n >>> 16);
44        bs[++off] = (byte)(n >>>  8);
45        bs[++off] = (byte)(n       );
46    }
47
48    public static byte[] intToBigEndian(int[] ns)
49    {
50        byte[] bs = new byte[4 * ns.length];
51        intToBigEndian(ns, bs, 0);
52        return bs;
53    }
54
55    public static void intToBigEndian(int[] ns, byte[] bs, int off)
56    {
57        for (int i = 0; i < ns.length; ++i)
58        {
59            intToBigEndian(ns[i], bs, off);
60            off += 4;
61        }
62    }
63
64    public static long bigEndianToLong(byte[] bs, int off)
65    {
66        int hi = bigEndianToInt(bs, off);
67        int lo = bigEndianToInt(bs, off + 4);
68        return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
69    }
70
71    public static void bigEndianToLong(byte[] bs, int off, long[] ns)
72    {
73        for (int i = 0; i < ns.length; ++i)
74        {
75            ns[i] = bigEndianToLong(bs, off);
76            off += 8;
77        }
78    }
79
80    public static byte[] longToBigEndian(long n)
81    {
82        byte[] bs = new byte[8];
83        longToBigEndian(n, bs, 0);
84        return bs;
85    }
86
87    public static void longToBigEndian(long n, byte[] bs, int off)
88    {
89        intToBigEndian((int)(n >>> 32), bs, off);
90        intToBigEndian((int)(n & 0xffffffffL), bs, off + 4);
91    }
92
93    public static byte[] longToBigEndian(long[] ns)
94    {
95        byte[] bs = new byte[8 * ns.length];
96        longToBigEndian(ns, bs, 0);
97        return bs;
98    }
99
100    public static void longToBigEndian(long[] ns, byte[] bs, int off)
101    {
102        for (int i = 0; i < ns.length; ++i)
103        {
104            longToBigEndian(ns[i], bs, off);
105            off += 8;
106        }
107    }
108
109    public static short littleEndianToShort(byte[] bs, int off)
110    {
111        int n = bs[  off] & 0xff;
112        n |= (bs[++off] & 0xff) << 8;
113        return (short)n;
114    }
115
116    public static int littleEndianToInt(byte[] bs, int off)
117    {
118        int n = bs[  off] & 0xff;
119        n |= (bs[++off] & 0xff) << 8;
120        n |= (bs[++off] & 0xff) << 16;
121        n |= bs[++off] << 24;
122        return n;
123    }
124
125    public static void littleEndianToInt(byte[] bs, int off, int[] ns)
126    {
127        for (int i = 0; i < ns.length; ++i)
128        {
129            ns[i] = littleEndianToInt(bs, off);
130            off += 4;
131        }
132    }
133
134    public static void littleEndianToInt(byte[] bs, int bOff, int[] ns, int nOff, int count)
135    {
136        for (int i = 0; i < count; ++i)
137        {
138            ns[nOff + i] = littleEndianToInt(bs, bOff);
139            bOff += 4;
140        }
141    }
142
143    public static int[] littleEndianToInt(byte[] bs, int off, int count)
144    {
145        int[] ns = new int[count];
146        for (int i = 0; i < ns.length; ++i)
147        {
148            ns[i] = littleEndianToInt(bs, off);
149            off += 4;
150        }
151        return ns;
152    }
153
154    public static byte[] shortToLittleEndian(short n)
155    {
156        byte[] bs = new byte[2];
157        shortToLittleEndian(n, bs, 0);
158        return bs;
159    }
160
161    public static void shortToLittleEndian(short n, byte[] bs, int off)
162    {
163        bs[  off] = (byte)(n       );
164        bs[++off] = (byte)(n >>>  8);
165    }
166
167    public static byte[] intToLittleEndian(int n)
168    {
169        byte[] bs = new byte[4];
170        intToLittleEndian(n, bs, 0);
171        return bs;
172    }
173
174    public static void intToLittleEndian(int n, byte[] bs, int off)
175    {
176        bs[  off] = (byte)(n       );
177        bs[++off] = (byte)(n >>>  8);
178        bs[++off] = (byte)(n >>> 16);
179        bs[++off] = (byte)(n >>> 24);
180    }
181
182    public static byte[] intToLittleEndian(int[] ns)
183    {
184        byte[] bs = new byte[4 * ns.length];
185        intToLittleEndian(ns, bs, 0);
186        return bs;
187    }
188
189    public static void intToLittleEndian(int[] ns, byte[] bs, int off)
190    {
191        for (int i = 0; i < ns.length; ++i)
192        {
193            intToLittleEndian(ns[i], bs, off);
194            off += 4;
195        }
196    }
197
198    public static long littleEndianToLong(byte[] bs, int off)
199    {
200        int lo = littleEndianToInt(bs, off);
201        int hi = littleEndianToInt(bs, off + 4);
202        return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
203    }
204
205    public static void littleEndianToLong(byte[] bs, int off, long[] ns)
206    {
207        for (int i = 0; i < ns.length; ++i)
208        {
209            ns[i] = littleEndianToLong(bs, off);
210            off += 8;
211        }
212    }
213
214    public static byte[] longToLittleEndian(long n)
215    {
216        byte[] bs = new byte[8];
217        longToLittleEndian(n, bs, 0);
218        return bs;
219    }
220
221    public static void longToLittleEndian(long n, byte[] bs, int off)
222    {
223        intToLittleEndian((int)(n & 0xffffffffL), bs, off);
224        intToLittleEndian((int)(n >>> 32), bs, off + 4);
225    }
226
227    public static byte[] longToLittleEndian(long[] ns)
228    {
229        byte[] bs = new byte[8 * ns.length];
230        longToLittleEndian(ns, bs, 0);
231        return bs;
232    }
233
234    public static void longToLittleEndian(long[] ns, byte[] bs, int off)
235    {
236        for (int i = 0; i < ns.length; ++i)
237        {
238            longToLittleEndian(ns[i], bs, off);
239            off += 8;
240        }
241    }
242}
243