/******************************************************************************* * $Id$ * $Author$ * $Date$ * * Copyright 2002-2003 YAJUL Developers, Joshua Davis, Kent Vogel. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * ******************************************************************************/ package org.yajul.util; /** * Yet another class that turns Java primatives into arrays of bytes, and back. * User: josh * Date: Jan 11, 2004 * Time: 10:18:58 PM */ public class Bytes { public static final int VALUE_UPPERCASE_A = 'A' - 10; public static final int VALUE_LOWERCASE_A = 'a' - 10; public static final String HEX_LOWER = "0123456789abcdef"; public static final String HEX_UPPER = "0123456789ABCDEF"; /** * Lowercase hex characters. */ public static final char[] HEX_CHARS_LOWER = HEX_LOWER.toCharArray(); /** * Uppercase hex characters. */ public static final char[] HEX_CHARS_UPPER = HEX_UPPER.toCharArray(); /** * Lowercase hex characters as bytes. */ public static final byte[] HEX_BYTES_LOWER = HEX_LOWER.getBytes(); /** * Uppercase hex characters as bytes. */ public static final byte[] HEX_BYTES_UPPER = HEX_UPPER.getBytes(); /** * Lower nybble mask. */ public static final int MASK = 0x0000000F; /** * Builds a 4-byte array from an int, MSB first. * * @param n The number to convert. * @param b The output array. * @return The output array (b). */ public static byte[] toBytes(int n, byte[] b) { // The LSB goes in the last byte. b[3] = (byte) (n); n >>>= 8; b[2] = (byte) (n); n >>>= 8; b[1] = (byte) (n); n >>>= 8; b[0] = (byte) (n); return b; } /** * Builds a 8-byte array from an int, MSB first. * * @param n The number to convert. * @param b The output array. * @return The output array (b). */ public static byte[] toBytes(long n, byte[] b) { // The LSB goes in the last byte. b[7] = (byte) (n); n >>>= 8; b[6] = (byte) (n); n >>>= 8; b[5] = (byte) (n); n >>>= 8; b[4] = (byte) (n); n >>>= 8; b[3] = (byte) (n); n >>>= 8; b[2] = (byte) (n); n >>>= 8; b[1] = (byte) (n); n >>>= 8; b[0] = (byte) (n); return b; } /** * Converts the byte into a two element array of hex characters. * * @param hexBytes The hex encoding set to use (e.g. HEX_BYTES_LOWER / * HEX_BYTES_UPPER). * @param inBytes The input byte array. * @param length The number of bytes to convert to hex. * @param out The output array of hex bytes. The length of this array * must be >= 2 * length. */ public static void hexBytes(final byte[] hexBytes, byte[] inBytes, byte[] out, int length) { byte inByte; int j; for (int i = 0; i < length; i++) { inByte = inBytes[i]; j = (i * 2); out[1 + j] = hexBytes[MASK & inByte]; // Get the lower nybble and set the second char. inByte >>= 4; // Shift off the lower nybble. out[j] = hexBytes[MASK & inByte]; // Get the upper nybble and set the first char. } } /** * Converts the byte into a two element array of hex characters. * * @param hexBytes The hex character set to use (e.g. HEX_BYTES_LOWER / HEX_BYTES_UPPER). * @param inByte The input byte. * @param out The output array of characters. Length must be >= 2. */ public static void hexBytes(final byte[] hexBytes, int inByte, byte[] out) { out[1] = hexBytes[MASK & inByte]; // Get the lower nybble and set the second char. inByte >>= 4; // Shift off the lower nybble. out[0] = hexBytes[MASK & inByte]; // Get the upper nybble and set the first char. } /** * Parses a hex string into an array of bytes. * * @param hexString the hex string * @return an array of bytes, parsed from the hex string */ public static byte[] parseHex(String hexString) { int length = hexString.length(); if ((length % 2) != 0) throw new IllegalArgumentException("Hex strings must have an even number of characters!"); int bytes = length / 2; if (bytes == 0) return new byte[0]; byte[] data = new byte[bytes]; char[] chars = hexString.toCharArray(); int byteValue = 0; for (int i = 0; i < length; i++) { char c = Character.toLowerCase(chars[i]); int number; if (c >= '0' && c <= '9') number = c - '0'; else if (c >= 'a' && c <= 'f') number = 10 + c - 'a'; else throw new IllegalArgumentException("Unexpected hex character: '" + c + "'"); if ((i % 2) == 0) byteValue = number * 16; else { byteValue += number; data[i / 2] = (byte) byteValue; } } return data; } }