ws.moor.bt.util.ByteUtil.java Source code

Java tutorial

Introduction

Here is the source code for ws.moor.bt.util.ByteUtil.java

Source

/*
 * BitThief - A Free Riding BitTorrent Client
 * Copyright (C) 2006 Patrick Moor <patrick@moor.ws>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 */

package ws.moor.bt.util;

import org.apache.commons.codec.binary.Hex;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.BitSet;
import java.util.Random;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

/**
 * TODO(pmoor): Javadoc
 */
public class ByteUtil {

    private static Random rnd = new Random();

    public static void int_to_b32(int i, byte[] bytes) {
        int_to_b32(i, bytes, 0);
    }

    public static void int_to_b32(int i, byte[] bytes, int offset) {
        bytes[offset + 0] = (byte) ((i >> 24) & 0xff);
        bytes[offset + 1] = (byte) ((i >> 16) & 0xff);
        bytes[offset + 2] = (byte) ((i >> 8) & 0xff);
        bytes[offset + 3] = (byte) ((i >> 0) & 0xff);
    }

    public static void int_to_l32(int i, byte[] bytes) {
        bytes[3] = (byte) ((i >> 24) & 0xff);
        bytes[2] = (byte) ((i >> 16) & 0xff);
        bytes[1] = (byte) ((i >> 8) & 0xff);
        bytes[0] = (byte) ((i >> 0) & 0xff);
    }

    public static byte[] newByteArray(int... bytes) {
        byte[] result = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] > 255 || bytes[i] < 0) {
                throw new IllegalArgumentException("all values must be 0 <= value < 256");
            }
            result[i] = (byte) bytes[i];
        }
        return result;
    }

    public static int b32_to_int(byte[] bytes, int offset) {
        return ((bytes[offset + 0] & 0xff) << 24) | ((bytes[offset + 1] & 0xff) << 16)
                | ((bytes[offset + 2] & 0xff) << 8) | ((bytes[offset + 3] & 0xff) << 0);
    }

    public static byte[] randomByteArray(int length) {
        byte[] result = new byte[length];
        rnd.nextBytes(result);
        return result;
    }

    public static int distance(byte[] a, byte[] b) {
        byte[] result = xor(a, b);
        if (result.length == 0) {
            result = new byte[] { 1 };
        }
        result = ArrayUtil.append(new byte[] { 0 }, result);
        BigDecimal number = new BigDecimal(new BigInteger(result));
        if (number.equals(BigDecimal.ZERO)) {
            number = BigDecimal.ONE;
        }
        double clear = BigDecimal.valueOf(2).pow(a.length * 8).divide(number, 4, RoundingMode.UP).doubleValue();
        return (int) (100.0 * Math.log(clear) / Math.log(2.0) / a.length);
    }

    public static BitSet toBitSet(byte[] bytes) {
        BitSet result = new BitSet();
        for (int i = 0; i < bytes.length * 8; i++) {
            if ((bytes[i / 8] & (1 << (7 - (i % 8)))) != 0) {
                result.set(i);
            }
        }
        return result;
    }

    public static byte[] xor(byte[] a, byte[] b) {
        if (a == null || b == null) {
            throw new NullPointerException("a and b must not be null");
        } else if (a.length != b.length) {
            throw new IllegalArgumentException("a and b must have the same length");
        }
        byte[] result = new byte[a.length];
        for (int i = 0; i < a.length; i++) {
            result[i] = (byte) (a[i] ^ b[i]);
        }
        return result;
    }

    public static int leftmostBit(byte[] bytes) {
        int bit = 0;
        while (bit / 8 < bytes.length && bytes[bit / 8] == 0) {
            bit += 8;
        }
        if (bit / 8 == bytes.length) {
            return -1;
        }
        byte byt = bytes[bit / 8];
        for (int i = 7; i >= 0; i--, bit++) {
            if ((byt & (1 << i)) != 0) {
                break;
            }
        }
        return bytes.length * 8 - bit - 1;
    }

    private static char[] urlEncodeMap = new char[256];
    static {
        for (char c = 'a'; c <= 'z'; c++) {
            urlEncodeMap[c] = c;
        }
        for (char c = 'A'; c <= 'Z'; c++) {
            urlEncodeMap[c] = c;
        }
        for (char c = '0'; c <= '9'; c++) {
            urlEncodeMap[c] = c;
        }
        urlEncodeMap['-'] = '-';
    }

    public static String urlEncode(byte[] array) {
        StringBuilder result = new StringBuilder(array.length * 3);
        for (byte byt : array) {
            int intval = byt & 0xff;
            if (urlEncodeMap[intval] > 0) {
                result.append(urlEncodeMap[intval]);
            } else {
                result.append('%');
                result.append(Hex.encodeHex(new byte[] { byt }));
            }
        }
        return result.toString();
    }
}