11package fr .devnied .bitlib ;
22
33import java .math .BigInteger ;
4- import java .util .Locale ;
54
65/**
76 * Class used to manage String/byte/int converter
8- *
7+ *
98 * @author Millau Julien
10- *
9+ *
1110 */
1211public final class BytesUtils {
1312
@@ -22,22 +21,45 @@ public final class BytesUtils {
2221 private static final int HEXA = 16 ;
2322
2423 /**
25- * No space format
24+ * Byte left mask
2625 */
27- private static final String FORMAT_NOSPACE = "%02x" ;
26+ private static final int LEFT_MASK = 0xF0 ;
27+
28+ /**
29+ * Byte right mask
30+ */
31+ private static final int RIGHT_MASK = 0xF ;
32+
33+ /**
34+ * Char digit 0 (0x30) :<br>
35+ * <ul>
36+ * <li>char 0 = 0x30 + 0x0
37+ * <li>char 1 = 0x30 + 0x1
38+ * <li>...
39+ * <li>char 9 = 0x30 + 0x9
40+ * </ul>
41+ */
42+ private static final int CHAR_DIGIT_ZERO = 0x30 ;
43+
2844 /**
29- * Space format
45+ * Char digit 7 (0x37) :<br>
46+ * <ul>
47+ * <li>char A = 0x37 + 0xA
48+ * <li>char B = 0x37 + 0xB
49+ * <li>...
50+ * <li>char F = 0x37 + 0xF
51+ * </ul>
3052 */
31- private static final String FORMAT_SPACE = "%02x " ;
53+ private static final int CHAR_DIGIT_SEVEN = 0x37 ;
3254
3355 /**
34- * Default mask
56+ * Char space
3557 */
36- private static final int DEFAULT_MASK = 0xFF ;
58+ private static final char CHAR_SPACE = ( char ) 0x20 ;
3759
3860 /**
3961 * Method used to convert byte array to int
40- *
62+ *
4163 * @param byteArray
4264 * byte array to convert
4365 * @return int value
@@ -51,7 +73,7 @@ public static int byteArrayToInt(final byte[] byteArray) {
5173
5274 /**
5375 * Method used to convert byte array to int
54- *
76+ *
5577 * @param byteArray
5678 * byte array to convert
5779 * @param startPos
@@ -79,95 +101,112 @@ public static int byteArrayToInt(final byte[] byteArray, final int startPos, fin
79101
80102 /**
81103 * Method to convert bytes to string with space between bytes
82- *
104+ *
83105 * @param pBytes
84- * Bytes to convert
85- *
106+ * Bytes to convert
107+ *
86108 * @return a string
87109 */
88110 public static String bytesToString (final byte [] pBytes ) {
89- return formatByte (pBytes , FORMAT_SPACE , false );
111+ return formatByte (pBytes , true , false );
90112 }
91113
92114 /**
93115 * Method to convert bytes to string with space between bytes
94- *
116+ *
95117 * bytes to convert
118+ *
96119 * @param pBytes
97- * Bytes to convert
120+ * Bytes to convert
98121 * @param pTruncate
99122 * true to remove 0 left byte value
100123 * @return a string
101124 */
102125 public static String bytesToString (final byte [] pBytes , final boolean pTruncate ) {
103- return formatByte (pBytes , FORMAT_SPACE , pTruncate );
126+ return formatByte (pBytes , true , pTruncate );
104127 }
105128
106129 /**
107130 * Method to convert byte to string without space between byte
108- *
131+ *
109132 * @param pByte
110133 * byte to convert
111134 * @return a string
112135 */
113136 public static String bytesToStringNoSpace (final byte pByte ) {
114- return formatByte (new byte [] { pByte }, FORMAT_NOSPACE , false );
137+ return formatByte (new byte [] { pByte }, false , false );
115138 }
116139
117140 /**
118141 * Method to convert bytes to string without space between bytes
119- *
142+ *
120143 * @param pBytes
121144 * bytes to convert
122145 * @return a string
123146 */
124147 public static String bytesToStringNoSpace (final byte [] pBytes ) {
125- return formatByte (pBytes , FORMAT_NOSPACE , false );
148+ return formatByte (pBytes , false , false );
126149 }
127150
128151 /**
129152 * Method to convert bytes to string without space between bytes
130- *
153+ *
131154 * @param pBytes
132155 * bytes to convert
133156 * @param pTruncate
134157 * true to remove 0 left byte value
135158 * @return a string
136159 */
137160 public static String bytesToStringNoSpace (final byte [] pBytes , final boolean pTruncate ) {
138- return formatByte (pBytes , FORMAT_NOSPACE , pTruncate );
161+ return formatByte (pBytes , false , pTruncate );
139162 }
140163
141164 /**
142- * Private method to format byte to hexa string
143- *
165+ * Private method to format bytes to hexa string
166+ *
144167 * @param pByte
145- * the byte to format
146- * @param pFormat
147- * the format
168+ * the bytes to format
169+ * @param pSpace
170+ * true if add spaces between bytes
148171 * @param pTruncate
149- * true to remove 0 left byte value
172+ * true to remove 0 left bytes value
150173 * @return a string containing the requested string
151174 */
152- private static String formatByte (final byte [] pByte , final String pFormat , final boolean pTruncate ) {
153- StringBuffer sb = new StringBuffer () ;
175+ private static String formatByte (final byte [] pByte , final boolean pSpace , final boolean pTruncate ) {
176+ String result ;
154177 if (pByte == null ) {
155- sb . append ( "" ) ;
178+ result = "" ;
156179 } else {
157- boolean t = false ;
158- for (byte b : pByte ) {
159- if (b != 0 || !pTruncate || t ) {
160- t = true ;
161- sb .append (String .format (pFormat , b & DEFAULT_MASK ));
180+ int i = 0 ;
181+ if (pTruncate ) {
182+ while (i < pByte .length && pByte [i ] == 0 ) {
183+ i ++;
184+ }
185+ }
186+ if (i < pByte .length ) {
187+ int sizeMultiplier = pSpace ? 3 : 2 ;
188+ char [] c = new char [(pByte .length - i ) * sizeMultiplier ];
189+ byte b ;
190+ for (int j = 0 ; i < pByte .length ; i ++, j ++) {
191+ b = (byte ) ((pByte [i ] & LEFT_MASK ) >> 4 );
192+ c [j ] = (char ) (b > 9 ? b + CHAR_DIGIT_SEVEN : b + CHAR_DIGIT_ZERO );
193+ b = (byte ) (pByte [i ] & RIGHT_MASK );
194+ c [++j ] = (char ) (b > 9 ? b + CHAR_DIGIT_SEVEN : b + CHAR_DIGIT_ZERO );
195+ if (pSpace ) {
196+ c [++j ] = CHAR_SPACE ;
197+ }
162198 }
199+ result = pSpace ? new String (c , 0 , c .length - 1 ) : new String (c );
200+ } else {
201+ result = "" ;
163202 }
164203 }
165- return sb . toString (). toUpperCase ( Locale . getDefault ()). trim () ;
204+ return result ;
166205 }
167206
168207 /**
169208 * Method to get bytes form string
170- *
209+ *
171210 * @param pData
172211 * String to parse
173212 * @return a table of string
@@ -176,22 +215,28 @@ public static byte[] fromString(final String pData) {
176215 if (pData == null ) {
177216 throw new IllegalArgumentException ("Argument can't be null" );
178217 }
179- String text = pData .replace (" " , "" );
180- if (text .length () % 2 != 0 ) {
218+ StringBuilder sb = new StringBuilder (pData );
219+ int j = 0 ;
220+ for (int i = 0 ; i < sb .length (); i ++) {
221+ if (!Character .isWhitespace (sb .charAt (i ))) {
222+ sb .setCharAt (j ++, sb .charAt (i ));
223+ }
224+ }
225+ sb .delete (j , sb .length ());
226+ if (sb .length () % 2 != 0 ) {
181227 throw new IllegalArgumentException ("Hex binary needs to be even-length :" + pData );
182228 }
183- byte [] commandByte = new byte [Math .round (text .length () / (float ) 2.0 )];
184- int j = 0 ;
185- for (int i = 0 ; i < text .length (); i += 2 ) {
186- Integer val = Integer .parseInt (text .substring (i , i + 2 ), HEXA );
187- commandByte [j ++] = val .byteValue ();
229+ byte [] result = new byte [sb .length () / 2 ];
230+ j = 0 ;
231+ for (int i = 0 ; i < sb .length (); i += 2 ) {
232+ result [j ++] = (byte ) ((Character .digit (sb .charAt (i ), 16 ) << 4 ) + Character .digit (sb .charAt (i + 1 ), 16 ));
188233 }
189- return commandByte ;
234+ return result ;
190235 }
191236
192237 /**
193238 * Test if bit at given index of given value is = 1.
194- *
239+ *
195240 * @param pVal
196241 * value to test
197242 * @param pBitIndex
@@ -200,14 +245,15 @@ public static byte[] fromString(final String pData) {
200245 */
201246 public static boolean matchBitByBitIndex (final int pVal , final int pBitIndex ) {
202247 if (pBitIndex < 0 || pBitIndex > MAX_BIT_INTEGER ) {
203- throw new IllegalArgumentException ("parameter 'pBitIndex' must be between 0 and 31. pBitIndex=" + pBitIndex );
248+ throw new IllegalArgumentException (
249+ "parameter 'pBitIndex' must be between 0 and 31. pBitIndex=" + pBitIndex );
204250 }
205251 return (pVal & 1 << pBitIndex ) != 0 ;
206252 }
207253
208254 /**
209255 * Method used to set a bit index to 1 or 0.
210- *
256+ *
211257 * @param pData
212258 * data to modify
213259 * @param pBitIndex
@@ -231,7 +277,7 @@ public static byte setBit(final byte pData, final int pBitIndex, final boolean p
231277
232278 /**
233279 * Convert byte array to binary String
234- *
280+ *
235281 * @param pBytes
236282 * byte array to convert
237283 * @return a binary representation of the byte array
@@ -252,14 +298,14 @@ public static String toBinary(final byte[] pBytes) {
252298
253299 /**
254300 * Method used to convert integer to byet array
255- *
301+ *
256302 * @param value
257303 * the value to convert
258304 * @return a byte array
259305 */
260306 public static byte [] toByteArray (final int value ) {
261307 return new byte [] { //
262- (byte ) (value >> 24 ), //
308+ (byte ) (value >> 24 ), //
263309 (byte ) (value >> 16 ), //
264310 (byte ) (value >> 8 ), //
265311 (byte ) value //
0 commit comments