package org.solmix.commons.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.List; import org.solmix.commons.util.DataUtils; /** * copy from java.nio.Bits * * @author solmix.f@gmail.com * @version $Id$ 2014年2月10日 */ public final class Bytes { /** * Swap byte */ public static short swap(short x) { return (short) ((x << 8) | ((x >> 8) & 0xff)); } public static byte[] swap(byte[] x) { int i, count, len; byte tmp; len = x.length; count = len / 2; for (i = 0; i < count; i++) { tmp = x[i]; x[i] = x[len - i - 1]; x[len - i - 1] = tmp; } return x; } /** * Swap byte */ public static char swap(char x) { return (char) ((x << 8) | ((x >> 8) & 0xff)); } /** * Swap byte */ public static int swap(int x) { return (swap((short) x) << 16) | (swap((short) (x >> 16)) & 0xffff); } /** * Swap byte */ public static long swap(long x) { return ((long) swap((int) (x)) << 32) | (swap((int) (x >> 32)) & 0xffffffffL); } public static char makeChar(byte b1, byte b0) { return (char) ((b1 << 8) | (b0 & 0xff)); } public static byte char1(char x) { return (byte) (x >> 8); } public static byte char0(char x) { return (byte) (x >> 0); } static public short makeShort(byte b1, byte b0) { return (short) ((b1 << 8) | (b0 & 0xff)); } public static byte short1(short x) { return (byte) (x >> 8); } public static byte short0(short x) { return (byte) (x >> 0); } static public int makeInt(byte b3, byte b2, byte b1, byte b0) { return ((((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | ((b0 & 0xff) << 0))); } static public long makeLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0) { return ((((long) b7 & 0xff) << 56) | (((long) b6 & 0xff) << 48) | (((long) b5 & 0xff) << 40) | (((long) b4 & 0xff) << 32) | (((long) b3 & 0xff) << 24) | (((long) b2 & 0xff) << 16) | (((long) b1 & 0xff) << 8) | (((long) b0 & 0xff) << 0)); } public static byte long7(long x) { return (byte)(x >> 56); } public static byte long6(long x) { return (byte)(x >> 48); } public static byte long5(long x) { return (byte)(x >> 40); } public static byte long4(long x) { return (byte)(x >> 32); } public static byte long3(long x) { return (byte)(x >> 24); } public static byte long2(long x) { return (byte)(x >> 16); } public static byte long1(long x) { return (byte)(x >> 8); } public static byte long0(long x) { return (byte)(x >> 0); } public static byte int3(int x) { return (byte) (x >> 24); } public static byte int2(int x) { return (byte) (x >> 16); } public static byte int1(int x) { return (byte) (x >> 8); } public static byte int0(int x) { return (byte) (x >> 0); } /** * Formate space split Hex string to byte. * @param str * @return */ public static byte[] formatStringToByte(String str){ if(str==null)return null; str=str.trim(); while(str.indexOf(" ")!=-1){ str.replace(" ", " "); } String[] bs=str.split(" "); byte[] res = new byte[bs.length]; for(int i=0;i<bs.length;i++){ res[i]= Short.valueOf(bs[i],16).byteValue(); } return res; } public static String byteToHexString(byte... src) { StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v).toUpperCase(); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv).append(" "); } return stringBuilder.toString(); } public static int add(int a, int b) { int carry, add; do { add = a ^ b; carry = (a & b) << 1; a = add; b = carry; } while (carry != 0); return add; } public static int subtract(int a, int b) { return add(a, add(~b, 1)); } public static int divide(int a, int b) { boolean neg = (a > 0) ^ (b > 0); if (a < 0) a = -a; if (b < 0) b = -b; if (a < b) return 0; int msb = 0; for (msb = 0; msb < 32; msb++) { if ((b << msb) >= a) break; } int q = 0; for (int i = msb; i >= 0; i--) { if ((b << i) > a) continue; q |= (1 << i); a -= (b << i); } if (neg) return -q; return q; } /** * @param buffers */ public static String byteToHexString(List<ByteBuffer> buffers) { StringBuffer sb= new StringBuffer(); for(ByteBuffer bf:buffers){ bf.rewind(); byte[] target= new byte[bf.limit()]; bf.get(target); sb.append(byteToHexString(target)); } return sb.toString(); } public static int BCDToInt(byte bcd){ return (0xff & (bcd>>4))*10 +(0xf & bcd); } public static byte IntToBCD2(int i){ return (byte) ((i/10)<<4|(i%10&0x0f)); } public static byte[] IntToBCD4(int i){ byte[] bytes= new byte[2]; bytes[0]= (byte) ((i/10)<<4|(i%10&0x0f)); bytes[1]= (byte) ((i/1000)<<4|(i/100)); return bytes; } public static int bytes2int(byte[] b, int off) { return ((b[off + 3] & 0xFF) << 0) + ((b[off + 2] & 0xFF) << 8) + ((b[off + 1] & 0xFF) << 16) + ((b[off + 0]) << 24); } /** * @param header * @param i * @return */ public static long bytes2long(byte[] b, int off) { return ((b[off + 7] & 0xFFL) << 0) + ((b[off + 6] & 0xFFL) << 8) + ((b[off + 5] & 0xFFL) << 16) + ((b[off + 4] & 0xFFL) << 24) + ((b[off + 3] & 0xFFL) << 32) + ((b[off + 2] & 0xFFL) << 40) + ((b[off + 1] & 0xFFL) << 48) + (((long) b[off + 0]) << 56); } public static void short2bytes(short v, byte[] b) { short2bytes(v, b, 0); } public static void short2bytes(short v, byte[] b, int off) { b[off + 1] = (byte) v; b[off + 0] = (byte) (v >>> 8); } public static void long2bytes(long v, byte[] b) { long2bytes(v, b, 0); } public static void long2bytes(long v, byte[] b, int off) { b[off + 7] = (byte) v; b[off + 6] = (byte) (v >>> 8); b[off + 5] = (byte) (v >>> 16); b[off + 4] = (byte) (v >>> 24); b[off + 3] = (byte) (v >>> 32); b[off + 2] = (byte) (v >>> 40); b[off + 1] = (byte) (v >>> 48); b[off + 0] = (byte) (v >>> 56); } public static void int2bytes(int v, byte[] b, int off) { b[off + 3] = (byte) v; b[off + 2] = (byte) (v >>> 8); b[off + 1] = (byte) (v >>> 16); b[off + 0] = (byte) (v >>> 24); } public static byte[] toBcdBits(String v) { return DataUtils.reversal(str2Bcd(v)); } /** * BCD to Integer String * * @param bytes * @return */ public static String bcd2Str(byte[] bytes) { StringBuffer temp = new StringBuffer(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { temp.append((byte) ((bytes[i] & 0xf0) >>> 4)); temp.append((byte) (bytes[i] & 0x0f)); } return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString(); } public static byte[] hexStringToByte(String hex) { // return hex.getBytes(); int len = (hex.length() / 2); byte[] result = new byte[len]; char[] achar = hex.toCharArray(); for (int i = 0; i < len; i++) { int pos = i * 2; result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1])); } return result; } private static byte toByte(char c) { byte b = (byte) "0123456789ABCDEF".indexOf(c); return b; } public static final String bytesToHexString(byte[] bArray) { StringBuffer sb = new StringBuffer(bArray.length); String sTemp; for (int i = 0; i < bArray.length; i++) { sTemp = Integer.toHexString(0xFF & bArray[i]); if (sTemp.length() < 2) sb.append(0); sb.append(sTemp.toUpperCase()); } return sb.toString(); } public static final Object bytesToObject(byte[] bytes) throws IOException, ClassNotFoundException { ByteArrayInputStream in = new ByteArrayInputStream(bytes); ObjectInputStream oi = new ObjectInputStream(in); Object o = oi.readObject(); oi.close(); return o; } public static final byte[] objectToBytes(Serializable s) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream ot = new ObjectOutputStream(out); ot.writeObject(s); ot.flush(); ot.close(); return out.toByteArray(); } public static final String objectToHexString(Serializable s) throws IOException { return bytesToHexString(objectToBytes(s)); } public static final Object hexStringToObject(String hex) throws IOException, ClassNotFoundException { return bytesToObject(hexStringToByte(hex)); } public static byte[] toBcdBitsCopy(byte[] target, String v) { return DataUtils.reversalCopy(target, str2Bcd(v)); } /** * Integer String to BCD * * @param asc * @return */ public static byte[] str2Bcd(String asc) { int len = asc.length(); int mod = len % 2; if (mod != 0) { asc = "0" + asc; len = asc.length(); } byte abt[] = new byte[len]; if (len >= 2) { len = len / 2; } byte bbt[] = new byte[len]; abt = asc.getBytes(); int j, k; for (int p = 0; p < asc.length() / 2; p++) { if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) { j = abt[2 * p] - '0'; } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) { j = abt[2 * p] - 'a' + 0x0a; } else { j = abt[2 * p] - 'A' + 0x0a; } if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) { k = abt[2 * p + 1] - '0'; } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) { k = abt[2 * p + 1] - 'a' + 0x0a; } else { k = abt[2 * p + 1] - 'A' + 0x0a; } int a = (j << 4) + k; byte b = (byte) a; bbt[p] = b; } return bbt; } }