1 package org.bouncycastle.util; 2 3 /** 4 * Utility methods for converting byte arrays into ints and longs, and back again. 5 */ 6 public abstract class Pack 7 { bigEndianToShort(byte[] bs, int off)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 bigEndianToInt(byte[] bs, int off)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 bigEndianToInt(byte[] bs, int off, int[] ns)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 bigEndianToInt(byte[] bs, int off, int[] ns, int nsOff, int nsLen)33 public static void bigEndianToInt(byte[] bs, int off, int[] ns, int nsOff, int nsLen) 34 { 35 for (int i = 0; i < nsLen; ++i) 36 { 37 ns[nsOff + i] = bigEndianToInt(bs, off); 38 off += 4; 39 } 40 } 41 intToBigEndian(int n)42 public static byte[] intToBigEndian(int n) 43 { 44 byte[] bs = new byte[4]; 45 intToBigEndian(n, bs, 0); 46 return bs; 47 } 48 intToBigEndian(int n, byte[] bs, int off)49 public static void intToBigEndian(int n, byte[] bs, int off) 50 { 51 bs[off] = (byte)(n >>> 24); 52 bs[++off] = (byte)(n >>> 16); 53 bs[++off] = (byte)(n >>> 8); 54 bs[++off] = (byte)(n); 55 } 56 intToBigEndian(int[] ns)57 public static byte[] intToBigEndian(int[] ns) 58 { 59 byte[] bs = new byte[4 * ns.length]; 60 intToBigEndian(ns, bs, 0); 61 return bs; 62 } 63 intToBigEndian(int[] ns, byte[] bs, int off)64 public static void intToBigEndian(int[] ns, byte[] bs, int off) 65 { 66 for (int i = 0; i < ns.length; ++i) 67 { 68 intToBigEndian(ns[i], bs, off); 69 off += 4; 70 } 71 } 72 intToBigEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)73 public static void intToBigEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) 74 { 75 for (int i = 0; i < nsLen; ++i) 76 { 77 intToBigEndian(ns[nsOff + i], bs, bsOff); 78 bsOff += 4; 79 } 80 } 81 bigEndianToLong(byte[] bs, int off)82 public static long bigEndianToLong(byte[] bs, int off) 83 { 84 int hi = bigEndianToInt(bs, off); 85 int lo = bigEndianToInt(bs, off + 4); 86 return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL); 87 } 88 bigEndianToLong(byte[] bs, int off, long[] ns)89 public static void bigEndianToLong(byte[] bs, int off, long[] ns) 90 { 91 for (int i = 0; i < ns.length; ++i) 92 { 93 ns[i] = bigEndianToLong(bs, off); 94 off += 8; 95 } 96 } 97 bigEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen)98 public static void bigEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen) 99 { 100 for (int i = 0; i < nsLen; ++i) 101 { 102 ns[nsOff + i] = bigEndianToLong(bs, bsOff); 103 bsOff += 8; 104 } 105 } 106 longToBigEndian(long n)107 public static byte[] longToBigEndian(long n) 108 { 109 byte[] bs = new byte[8]; 110 longToBigEndian(n, bs, 0); 111 return bs; 112 } 113 longToBigEndian(long n, byte[] bs, int off)114 public static void longToBigEndian(long n, byte[] bs, int off) 115 { 116 intToBigEndian((int)(n >>> 32), bs, off); 117 intToBigEndian((int)(n & 0xffffffffL), bs, off + 4); 118 } 119 longToBigEndian(long[] ns)120 public static byte[] longToBigEndian(long[] ns) 121 { 122 byte[] bs = new byte[8 * ns.length]; 123 longToBigEndian(ns, bs, 0); 124 return bs; 125 } 126 longToBigEndian(long[] ns, byte[] bs, int off)127 public static void longToBigEndian(long[] ns, byte[] bs, int off) 128 { 129 for (int i = 0; i < ns.length; ++i) 130 { 131 longToBigEndian(ns[i], bs, off); 132 off += 8; 133 } 134 } 135 longToBigEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)136 public static void longToBigEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) 137 { 138 for (int i = 0; i < nsLen; ++i) 139 { 140 longToBigEndian(ns[nsOff + i], bs, bsOff); 141 bsOff += 8; 142 } 143 } 144 145 /** 146 * @param value The number 147 * @param bs The target. 148 * @param off Position in target to start. 149 * @param bytes number of bytes to write. 150 * 151 * @deprecated Will be removed 152 */ longToBigEndian(long value, byte[] bs, int off, int bytes)153 public static void longToBigEndian(long value, byte[] bs, int off, int bytes) 154 { 155 for (int i = bytes - 1; i >= 0; i--) 156 { 157 bs[i + off] = (byte)(value & 0xff); 158 value >>>= 8; 159 } 160 } 161 littleEndianToShort(byte[] bs, int off)162 public static short littleEndianToShort(byte[] bs, int off) 163 { 164 int n = bs[off] & 0xff; 165 n |= (bs[++off] & 0xff) << 8; 166 return (short)n; 167 } 168 littleEndianToInt(byte[] bs, int off)169 public static int littleEndianToInt(byte[] bs, int off) 170 { 171 int n = bs[off] & 0xff; 172 n |= (bs[++off] & 0xff) << 8; 173 n |= (bs[++off] & 0xff) << 16; 174 n |= bs[++off] << 24; 175 return n; 176 } 177 littleEndianToInt(byte[] bs, int off, int[] ns)178 public static void littleEndianToInt(byte[] bs, int off, int[] ns) 179 { 180 for (int i = 0; i < ns.length; ++i) 181 { 182 ns[i] = littleEndianToInt(bs, off); 183 off += 4; 184 } 185 } 186 littleEndianToInt(byte[] bs, int bOff, int[] ns, int nOff, int count)187 public static void littleEndianToInt(byte[] bs, int bOff, int[] ns, int nOff, int count) 188 { 189 for (int i = 0; i < count; ++i) 190 { 191 ns[nOff + i] = littleEndianToInt(bs, bOff); 192 bOff += 4; 193 } 194 } 195 littleEndianToInt(byte[] bs, int off, int count)196 public static int[] littleEndianToInt(byte[] bs, int off, int count) 197 { 198 int[] ns = new int[count]; 199 for (int i = 0; i < ns.length; ++i) 200 { 201 ns[i] = littleEndianToInt(bs, off); 202 off += 4; 203 } 204 return ns; 205 } 206 shortToLittleEndian(short n)207 public static byte[] shortToLittleEndian(short n) 208 { 209 byte[] bs = new byte[2]; 210 shortToLittleEndian(n, bs, 0); 211 return bs; 212 } 213 shortToLittleEndian(short n, byte[] bs, int off)214 public static void shortToLittleEndian(short n, byte[] bs, int off) 215 { 216 bs[off] = (byte)(n); 217 bs[++off] = (byte)(n >>> 8); 218 } 219 220 shortToBigEndian(short n)221 public static byte[] shortToBigEndian(short n) 222 { 223 byte[] r = new byte[2]; 224 shortToBigEndian(n, r, 0); 225 return r; 226 } 227 shortToBigEndian(short n, byte[] bs, int off)228 public static void shortToBigEndian(short n, byte[] bs, int off) 229 { 230 bs[off] = (byte)(n >>> 8); 231 bs[++off] = (byte)(n); 232 } 233 234 intToLittleEndian(int n)235 public static byte[] intToLittleEndian(int n) 236 { 237 byte[] bs = new byte[4]; 238 intToLittleEndian(n, bs, 0); 239 return bs; 240 } 241 intToLittleEndian(int n, byte[] bs, int off)242 public static void intToLittleEndian(int n, byte[] bs, int off) 243 { 244 bs[off] = (byte)(n); 245 bs[++off] = (byte)(n >>> 8); 246 bs[++off] = (byte)(n >>> 16); 247 bs[++off] = (byte)(n >>> 24); 248 } 249 intToLittleEndian(int[] ns)250 public static byte[] intToLittleEndian(int[] ns) 251 { 252 byte[] bs = new byte[4 * ns.length]; 253 intToLittleEndian(ns, bs, 0); 254 return bs; 255 } 256 intToLittleEndian(int[] ns, byte[] bs, int off)257 public static void intToLittleEndian(int[] ns, byte[] bs, int off) 258 { 259 for (int i = 0; i < ns.length; ++i) 260 { 261 intToLittleEndian(ns[i], bs, off); 262 off += 4; 263 } 264 } 265 intToLittleEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)266 public static void intToLittleEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) 267 { 268 for (int i = 0; i < nsLen; ++i) 269 { 270 intToLittleEndian(ns[nsOff + i], bs, bsOff); 271 bsOff += 4; 272 } 273 } 274 littleEndianToLong(byte[] bs, int off)275 public static long littleEndianToLong(byte[] bs, int off) 276 { 277 int lo = littleEndianToInt(bs, off); 278 int hi = littleEndianToInt(bs, off + 4); 279 return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL); 280 } 281 littleEndianToLong(byte[] bs, int off, long[] ns)282 public static void littleEndianToLong(byte[] bs, int off, long[] ns) 283 { 284 for (int i = 0; i < ns.length; ++i) 285 { 286 ns[i] = littleEndianToLong(bs, off); 287 off += 8; 288 } 289 } 290 littleEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen)291 public static void littleEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen) 292 { 293 for (int i = 0; i < nsLen; ++i) 294 { 295 ns[nsOff + i] = littleEndianToLong(bs, bsOff); 296 bsOff += 8; 297 } 298 } 299 longToLittleEndian(long n)300 public static byte[] longToLittleEndian(long n) 301 { 302 byte[] bs = new byte[8]; 303 longToLittleEndian(n, bs, 0); 304 return bs; 305 } 306 longToLittleEndian(long n, byte[] bs, int off)307 public static void longToLittleEndian(long n, byte[] bs, int off) 308 { 309 intToLittleEndian((int)(n & 0xffffffffL), bs, off); 310 intToLittleEndian((int)(n >>> 32), bs, off + 4); 311 } 312 longToLittleEndian(long[] ns)313 public static byte[] longToLittleEndian(long[] ns) 314 { 315 byte[] bs = new byte[8 * ns.length]; 316 longToLittleEndian(ns, bs, 0); 317 return bs; 318 } 319 longToLittleEndian(long[] ns, byte[] bs, int off)320 public static void longToLittleEndian(long[] ns, byte[] bs, int off) 321 { 322 for (int i = 0; i < ns.length; ++i) 323 { 324 longToLittleEndian(ns[i], bs, off); 325 off += 8; 326 } 327 } 328 longToLittleEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)329 public static void longToLittleEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) 330 { 331 for (int i = 0; i < nsLen; ++i) 332 { 333 longToLittleEndian(ns[nsOff + i], bs, bsOff); 334 bsOff += 8; 335 } 336 } 337 } 338