svn-gvsig-desktop / trunk / libraries / libDwg / src / freenet / support / HexUtil.java @ 2896
History | View | Annotate | Download (4.17 KB)
1 |
package freenet.support; |
---|---|
2 |
|
3 |
import java.util.BitSet; |
4 |
|
5 |
/**
|
6 |
* Number in hexadecimal format are used throughout Freenet.
|
7 |
*
|
8 |
* <p>Unless otherwise stated, the conventions follow the rules outlined in the
|
9 |
* Java Language Specification.</p>
|
10 |
*
|
11 |
* @author syoung
|
12 |
*/
|
13 |
public class HexUtil { |
14 |
private HexUtil() {
|
15 |
} |
16 |
|
17 |
|
18 |
/**
|
19 |
* Converts a byte array into a string of upper case hex chars.
|
20 |
*
|
21 |
* @param bs
|
22 |
* A byte array
|
23 |
* @param off
|
24 |
* The index of the first byte to read
|
25 |
* @param length
|
26 |
* The number of bytes to read.
|
27 |
* @return the string of hex chars.
|
28 |
*/
|
29 |
public static final String bytesToHex(byte[] bs, int off, int length) { |
30 |
StringBuffer sb = new StringBuffer(length * 2); |
31 |
bytesToHexAppend(bs, off, length, sb); |
32 |
return sb.toString();
|
33 |
} |
34 |
|
35 |
public static final void bytesToHexAppend( |
36 |
byte[] bs, |
37 |
int off,
|
38 |
int length,
|
39 |
StringBuffer sb) {
|
40 |
sb.ensureCapacity(sb.length() + length * 2);
|
41 |
for (int i = off; i < (off + length) && i < bs.length; i++) { |
42 |
sb.append(Character.forDigit((bs[i] >>> 4) & 0xf, 16)); |
43 |
sb.append(Character.forDigit(bs[i] & 0xf, 16)); |
44 |
} |
45 |
} |
46 |
|
47 |
public static final String bytesToHex(byte[] bs) { |
48 |
return bytesToHex(bs, 0, bs.length); |
49 |
} |
50 |
|
51 |
public static final byte[] hexToBytes(String s) { |
52 |
return hexToBytes(s, 0); |
53 |
} |
54 |
|
55 |
public static final byte[] hexToBytes(String s, int off) { |
56 |
byte[] bs = new byte[off + (1 + s.length()) / 2]; |
57 |
hexToBytes(s, bs, off); |
58 |
return bs;
|
59 |
} |
60 |
|
61 |
/**
|
62 |
* Converts a String of hex characters into an array of bytes.
|
63 |
*
|
64 |
* @param s
|
65 |
* A string of hex characters (upper case or lower) of even
|
66 |
* length.
|
67 |
* @param out
|
68 |
* A byte array of length at least s.length()/2 + off
|
69 |
* @param off
|
70 |
* The first byte to write of the array
|
71 |
*/
|
72 |
public static final void hexToBytes(String s, byte[] out, int off) |
73 |
throws NumberFormatException, IndexOutOfBoundsException { |
74 |
int slen = s.length();
|
75 |
if ((slen % 2) != 0) { |
76 |
s = '0' + s;
|
77 |
} |
78 |
|
79 |
if (out.length < off + slen / 2) { |
80 |
throw new IndexOutOfBoundsException( |
81 |
"Output buffer too small for input ("
|
82 |
+ out.length |
83 |
+ "<"
|
84 |
+ off |
85 |
+ slen / 2
|
86 |
+ ")");
|
87 |
} |
88 |
|
89 |
// Safe to assume the string is even length
|
90 |
byte b1, b2;
|
91 |
for (int i = 0; i < slen; i += 2) { |
92 |
b1 = (byte) Character.digit(s.charAt(i), 16); |
93 |
b2 = (byte) Character.digit(s.charAt(i + 1), 16); |
94 |
if (b1 < 0 || b2 < 0) { |
95 |
throw new NumberFormatException(); |
96 |
} |
97 |
out[off + i / 2] = (byte) (b1 << 4 | b2); |
98 |
} |
99 |
} |
100 |
|
101 |
/**
|
102 |
* Pack the bits in ba into a byte[].
|
103 |
*/
|
104 |
public final static byte[] bitsToBytes(BitSet ba, int size) { |
105 |
int bytesAlloc = countBytesForBits(size);
|
106 |
byte[] b = new byte[bytesAlloc]; |
107 |
StringBuffer sb = new StringBuffer(); |
108 |
for(int i=0;i<b.length;i++) { |
109 |
short s = 0; |
110 |
for(int j=0;j<8;j++) { |
111 |
int idx = i*8+j; |
112 |
boolean val =
|
113 |
idx > size ? false :
|
114 |
ba.get(idx); |
115 |
s |= val ? (1<<j) : 0; |
116 |
sb.append(val ? '1' : '0'); |
117 |
} |
118 |
if(s > 255) throw new IllegalStateException("WTF? s = "+s); |
119 |
b[i] = (byte)s;
|
120 |
} |
121 |
return b;
|
122 |
} |
123 |
|
124 |
/**
|
125 |
* Pack the bits in ba into a byte[] then convert that
|
126 |
* to a hex string and return it.
|
127 |
*/
|
128 |
public final static String bitsToHexString(BitSet ba, int size) { |
129 |
return bytesToHex(bitsToBytes(ba, size));
|
130 |
} |
131 |
|
132 |
|
133 |
/**
|
134 |
* @return the number of bytes required to represent the
|
135 |
* bitset
|
136 |
*/
|
137 |
public static int countBytesForBits(int size) { |
138 |
// Brackets matter here! == takes precedence over the rest
|
139 |
return (size/8) + ((size % 8) == 0 ? 0:1); |
140 |
} |
141 |
|
142 |
|
143 |
/**
|
144 |
* Read bits from a byte array into a bitset
|
145 |
* @param b the byte[] to read from
|
146 |
* @param ba the bitset to write to
|
147 |
*/
|
148 |
public static void bytesToBits(byte[] b, BitSet ba, int maxSize) { |
149 |
int x = 0; |
150 |
for(int i=0;i<b.length;i++) { |
151 |
for(int j=0;j<8;j++) { |
152 |
if(x > maxSize) break; |
153 |
int mask = 1 << j; |
154 |
boolean value = (mask & b[i]) != 0; |
155 |
ba.set(x, value); |
156 |
x++; |
157 |
} |
158 |
} |
159 |
} |
160 |
|
161 |
|
162 |
/**
|
163 |
* Read a hex string of bits and write it into a bitset
|
164 |
* @param s hex string of the stored bits
|
165 |
* @param ba the bitset to store the bits in
|
166 |
* @param length the maximum number of bits to store
|
167 |
*/
|
168 |
public static void hexToBits(String s, BitSet ba, int length) { |
169 |
byte[] b = hexToBytes(s); |
170 |
bytesToBits(b, ba, length); |
171 |
} |
172 |
} |