public   class  ByteUtil {
    
    
/**
     * Convert a String of hexadecimal digits into the corresponding byte array
     * by encoding each two hexadecimal digits as a byte.
     * 
     * 
@param  digits
     *            Hexadecimal digits representation
     * 
     * 
@exception  IllegalArgumentException
     *                if an invalid hexadecimal digit is found, or the input
     *                string contains an odd number of hexadecimal digits
     
*/
    
public   static   byte [] hexStringToByteArray(String digits) {
        ByteArrayOutputStream baos 
=   new  ByteArrayOutputStream();
        
for  ( int  i  =   0 ; i  <  digits.length(); i  +=   2 ) {
            
char  c1  =  digits.charAt(i);
            
if  ((i  +   1 >=  digits.length()) {
                
throw   new  IllegalArgumentException( " hexUtil.odd " );
            }
            
char  c2  =  digits.charAt(i  +   1 );
            
byte  b  =   0 ;
            
if  ((c1  >=   ' 0 ' &&  (c1  <=   ' 9 ' ))
                b 
+=  ((c1  -   ' 0 ' *   16 );
            
else   if  ((c1  >=   ' a ' &&  (c1  <=   ' f ' ))
                b 
+=  ((c1  -   ' a '   +   10 *   16 );
            
else   if  ((c1  >=   ' A ' &&  (c1  <=   ' F ' ))
                b 
+=  ((c1  -   ' A '   +   10 *   16 );
            
else
                
throw   new  IllegalArgumentException( " hexUtil.bad " );

            
if  ((c2  >=   ' 0 ' &&  (c2  <=   ' 9 ' ))
                b 
+=  (c2  -   ' 0 ' );
            
else   if  ((c2  >=   ' a ' &&  (c2  <=   ' f ' ))
                b 
+=  (c2  -   ' a '   +   10 );
            
else   if  ((c2  >=   ' A ' &&  (c2  <=   ' F ' ))
                b 
+=  (c2  -   ' A '   +   10 );
            
else
                
throw   new  IllegalArgumentException( " hexUtil.bad " );
            baos.write(b);
        }
        
return  (baos.toByteArray());

    }

    
/**
     * Convert a byte array into a printable format containing a String of
     * hexadecimal digit characters (two per byte).
     * 
@see  this method consume too much memory, especailly when large byte array.
     * 
     * 
@param  bytes
     *            Byte array representation
     
*/
    
public   static  String convertByteArrayToHexStr( byte  bytes[]) {

        StringBuffer sb 
=   new  StringBuffer(bytes.length * 2 );
        
for  ( int  i  =   0 ; i  <  bytes.length; i ++ ) {
            sb.append(convertDigitToHexChar((
int ) (bytes[i]  >>   4 )));
            sb.append(convertDigitToHexChar((
int ) (bytes[i]  &   0x0f )));
        }
        
return  (sb.toString());

    }
    
    
/**
     * convert byte array into hex string, with , as seperator
     * 
@see  this method consume too much memory, especailly when large byte array.
     * 
@param  bytes
     * 
@return
     
*/
    
public   static  String convertByteArrayToHexStr2( byte  bytes[]) {

        StringBuffer sb 
=   new  StringBuffer();
        
for  ( int  i  =   0 ; i  <  bytes.length; i ++ ) {
            sb.append(convertDigitToHexChar((
int ) (bytes[i]  >>   4 )));
            sb.append(convertDigitToHexChar((
int ) (bytes[i]  &   0x0f )));
            sb.append(
" , " );
        }
        
return  (sb.toString().substring( 0 ,sb.length() - 1 ));

    }

    
/**
     * Convert the specified value (0 .. 15, i.e. 4bits) to the corresponding hexadecimal
     * digit.
     * 
     * 
@param  value
     *            Value to be converted
     
*/
    
private   static   char  convertDigitToHexChar( int  value) {
        value 
=  value  &   0x0f ;
        
if  (value  >=   10 )
            
return  (( char ) (value  -   10   +   ' a ' ));
        
else
            
return  (( char ) (value  +   ' 0 ' ));

    }
    
    
    
public   static  String convertByteToHexStr( byte  value) {
        StringBuffer sb 
=   new  StringBuffer();
        sb.append(convertDigitToHexChar((
int ) (value  >>   4 )));
        sb.append(convertDigitToHexChar((
int ) (value  &   0x0f )));

        
return  (sb.toString());

    }

    
/**
     * Convert an int to a byte array
     * 
     * 
@param  value  int
     * 
@return  byte[]
     
*/
    
public   static   byte [] intToByteArray( int  value) {
        
byte [] b  =   new   byte [ 4 ];

        
for  ( int  i  =   0 ; i  <   4 ; i ++ ) {
            
int  offset  =  (b.length  -   1   -  i)  *   8
            b[i] 
=  ( byte ) ((value  >>  offset)  &   0xFF );  //  
        }
        
return  b;
    }
    
    
/**
     * change byte array into a unsigned byte array
     * 
@param  source
     * 
@return
     
*/
    
public   static   byte [] toUnsignedByteArray( byte [] source){
//         ByteUtil.printByteArray(source);
        
//  to keep value in the 0-255
         int  model =    256 ;
        
if (source == null   ||  source.length == 0 ){
            
return   new   byte [ 0 ];
        }
        
byte [] dest =   new   byte [source.length];
        
for ( int  i = 0 ;i < source.length;i ++ ){
            
int  tmp  =  ((source[i]  +  model)  %  model)  &   0xff ;
            dest[i] 
=  ( byte )tmp;
        }
        
return  dest;
    }

    
/**
     * Convert the byte array to an int starting from the given offset.
     * 
     * 
@param  b
     *            The byte array
     * 
@param  offset
     *            
     * 
@return  The integer
     
*/

    
public   static   int  byteArrayToInt( byte [] b) {
        
if (b.length > 4 ){
            
throw   new  RuntimeException( " more than 4 byte " );
        }
        
int  value  =   0 ;
        
for  ( int  i  =   0 ; i  <  b.length; i ++ ) {
            
int  shift  =  (b.length  -   1   -  i)  *   8 ;
            value 
+=  (b[i]  &   0xFF <<  shift;
        }
        
return  value;
    }
}