/* * Copyright (C) 2012 tamtam180 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.orz.hash; import java.math.BigInteger; /** * byte配列を整数に変換するユーティリティクラス。 * @author tamtam180 - kirscheless at gmail.com * */ public class EncodeUtils { public static interface EndianReader { int toInt(byte[] b, int i); long toLong(byte[] b, int i); } private static class LittleEndianReader implements EndianReader { public int toInt(byte[] b, int i) { return toIntLE(b, i); } public long toLong(byte[] b, int i) { return toLongLE(b, i); } } private static class BigEndianReader implements EndianReader { public int toInt(byte[] b, int i) { return toIntBE(b, i); } public long toLong(byte[] b, int i) { return toLongBE(b, i); } } public static final LittleEndianReader LEReader = new LittleEndianReader(); public static final BigEndianReader BEReader = new BigEndianReader(); /** * byte配列のi番目から4バイト読み取り、BigEndianとみなした整数を返す。 * @param b データ * @param i オフセット * @return BigEndianとみなした整数 */ public static int toIntBE(byte[] b, int i) { return (((b[i+0] & 255) << 24) + ((b[i+1] & 255) << 16) + ((b[i+2] & 255) << 8) + ((b[i+3] & 255) << 0)); } /** * byte配列のi番目から4バイト読み取り、LittleEndianとみなした整数を返す。 * @param b データ * @param i オフセット * @return LittleEndianとみなした整数 */ public static int toIntLE(byte[] b, int i) { return (((b[i+3] & 255) << 24) + ((b[i+2] & 255) << 16) + ((b[i+1] & 255) << 8) + ((b[i+0] & 255) << 0)); } /** * byte配列のi番目から8バイト読み取り、BigEndianとみなした整数を返す。 * @param b データ * @param i オフセット * @return BigEndianとみなした整数 */ public static long toLongBE(byte[] b, int i) { return (((long)b[i+0] << 56) + ((long)(b[i+1] & 255) << 48) + ((long)(b[i+2] & 255) << 40) + ((long)(b[i+3] & 255) << 32) + ((long)(b[i+4] & 255) << 24) + ((b[i+5] & 255) << 16) + ((b[i+6] & 255) << 8) + ((b[i+7] & 255) << 0)); } /** * byte配列のi番目から8バイト読み取り、LittleEndianとみなした整数を返す。 * @param b データ * @param i オフセット * @return LittleEndianとみなした整数 */ public static long toLongLE(byte[] b, int i) { return (((long)b[i+7] << 56) + ((long)(b[i+6] & 255) << 48) + ((long)(b[i+5] & 255) << 40) + ((long)(b[i+4] & 255) << 32) + ((long)(b[i+3] & 255) << 24) + ((b[i+2] & 255) << 16) + ((b[i+1] & 255) << 8) + ((b[i+0] & 255) << 0)); } /** * 8バイト整数をビッグエンディアンのバイト配列に変換。 * @param v * @return */ public static byte[] toBytesBE(long v) { return new byte[]{ (byte) (v >>> 56), (byte) (v >>> 48), (byte) (v >>> 40), (byte) (v >>> 32), (byte) (v >>> 24), (byte) (v >>> 16), (byte) (v >>> 8), (byte) (v >>> 0), }; } /** * 4バイト整数をビッグエンディアンのバイト配列に変換。 * @param v * @return */ public static byte[] toBytesBE(int v) { return new byte[] { (byte) ((v >>> 24) & 0xFF), (byte) ((v >>> 16) & 0xFF), (byte) ((v >>> 8) & 0xFF), (byte) ((v >>> 0) & 0xFF) }; } /** * unsignedな値に変換する。 * @param value signed-int値 * @return unsigned-int値 */ public static long toUnsigned(int value) { return 0xffffffffL & value; } /** * unsignedな値に変換する。 * @param value * @return */ public static BigInteger toUnsigned(long value) { byte[] v = toBytesBE(value); byte[] vv = new byte[v.length+1]; System.arraycopy(v, 0, vv, 1, v.length); return new BigInteger(vv); } /** * unsignedな値に変換する。 * @param values * @return */ public static BigInteger toUnsigned(int[] values) { byte[] buffer = new byte[values.length * 4+1]; for (int i = 0; i < values.length; i++) { byte[] ival = toBytesBE(values[i]); System.arraycopy(ival, 0, buffer, i * 4 + 1, 4); } return new BigInteger(buffer); } /** * unsignedな値に変換する。 * @param values * @return */ public static BigInteger toUnsigned(long[] values) { byte[] buffer = new byte[values.length * 8 + 1]; for (int i = 0; i < values.length; i++) { byte[] ival = toBytesBE(values[i]); System.arraycopy(ival, 0, buffer, i * 8 + 1, 8); } return new BigInteger(buffer); } }