Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #24481 > unrolled thread

convert byte array to hex string using BigInteger

Started byLaura Schmidt <ls@mailinator.com>
First post2013-06-20 14:03 +0200
Last post2013-11-24 10:43 +0000
Articles 20 on this page of 27 — 12 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  convert byte array to hex string using BigInteger Laura Schmidt <ls@mailinator.com> - 2013-06-20 14:03 +0200
    Re: convert byte array to hex string using BigInteger Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-06-20 09:03 -0400
    Re: convert byte array to hex string using BigInteger rossum <rossum48@coldmail.com> - 2013-06-20 14:09 +0100
      Re: convert byte array to hex string using BigInteger Laura Schmidt <ls@mailinator.com> - 2013-06-20 15:32 +0200
        Re: convert byte array to hex string using BigInteger rossum <rossum48@coldmail.com> - 2013-06-20 15:44 +0100
        Re: convert byte array to hex string using BigInteger lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-06-20 19:22 +0100
          Re: convert byte array to hex string using BigInteger markspace <markspace@nospam.nospam> - 2013-06-20 11:56 -0700
            Re: convert byte array to hex string using BigInteger lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-06-20 20:43 +0100
          Re: convert byte array to hex string using BigInteger Lew <lewbloch@gmail.com> - 2013-06-20 13:39 -0700
            Re: convert byte array to hex string using BigInteger lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-06-21 08:17 +0100
          Re: convert byte array to hex string using BigInteger Arne Vajhøj <arne@vajhoej.dk> - 2013-06-26 22:16 -0400
    Re: convert byte array to hex string using BigInteger Joerg Meier <joergmmeier@arcor.de> - 2013-06-20 22:09 +0200
    Re: convert byte array to hex string using BigInteger Roedy Green <see_website@mindprod.com.invalid> - 2013-06-21 14:51 -0700
      Re: convert byte array to hex string using BigInteger Joerg Meier <joergmmeier@arcor.de> - 2013-06-22 00:26 +0200
        Re: convert byte array to hex string using BigInteger Roedy Green <see_website@mindprod.com.invalid> - 2013-06-23 08:49 -0700
          Re: convert byte array to hex string using BigInteger Joerg Meier <joergmmeier@arcor.de> - 2013-06-23 22:37 +0200
        Re: convert byte array to hex string using BigInteger Roedy Green <see_website@mindprod.com.invalid> - 2013-06-23 12:40 -0700
          Re: convert byte array to hex string using BigInteger Joerg Meier <joergmmeier@arcor.de> - 2013-06-23 22:41 +0200
    Re: convert byte array to hex string using BigInteger Arne Vajhøj <arne@vajhoej.dk> - 2013-06-26 22:12 -0400
      Re: convert byte array to hex string using BigInteger Arne Vajhøj <arne@vajhoej.dk> - 2013-06-26 22:20 -0400
      Re: convert byte array to hex string using BigInteger Laura Schmidt <ls@mailinator.com> - 2013-06-28 07:55 +0200
        Re: convert byte array to hex string using BigInteger Joerg Meier <joergmmeier@arcor.de> - 2013-06-29 00:01 +0200
      Re: convert byte array to hex string using BigInteger Stanimir Stamenkov <s7an10@netscape.net> - 2013-06-29 19:10 +0300
        Re: convert byte array to hex string using BigInteger Arne Vajhøj <arne@vajhoej.dk> - 2013-07-03 22:24 -0400
    Re: convert byte array to hex string using BigInteger aydin.k.abadi@gmail.com - 2013-11-23 16:40 -0800
    Re: convert byte array to hex string using BigInteger aydin.k.abadi@gmail.com - 2013-11-23 16:43 -0800
      Re: convert byte array to hex string using BigInteger Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-24 10:43 +0000

Page 1 of 2  [1] 2  Next page →


#24481 — convert byte array to hex string using BigInteger

FromLaura Schmidt <ls@mailinator.com>
Date2013-06-20 14:03 +0200
Subjectconvert byte array to hex string using BigInteger
Message-ID<kpur29$5v4$1@news.albasani.net>
Hi,

I try to convert a byte array to a hex string like this:

  private static String hex_encode (byte [] val)
  {
   BigInteger b = new BigInteger(val);

   String t = b.toString(16);

   return (t);
  }

For a long byte array it returns a "negative" hex string, i. e. starting 
with a "-" sign.

But I want just the bytes in the array converted to hex representation, 
each one ranging from "00" to "FF". There should be no minus sign then.

Can you help?
Thanks!

Laura

[toc] | [next] | [standalone]


#24483

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2013-06-20 09:03 -0400
Message-ID<kpuu9p$mgu$1@dont-email.me>
In reply to#24481
On 6/20/2013 8:03 AM, Laura Schmidt wrote:
> Hi,
>
> I try to convert a byte array to a hex string like this:
>
>   private static String hex_encode (byte [] val)
>   {
>    BigInteger b = new BigInteger(val);
>
>    String t = b.toString(16);
>
>    return (t);
>   }
>
> For a long byte array it returns a "negative" hex string, i. e. starting
> with a "-" sign.
>
> But I want just the bytes in the array converted to hex representation,
> each one ranging from "00" to "FF". There should be no minus sign then.
>
> Can you help?

	// Untested:
	private static String hexEncode(byte[] val) {
	    StringBuilder buff = new StringBuilder(2 * val.length);
	    for (byte b : val) {
	        buff.append("0123456789ABCDEF".charAt((b >> 4) & 0xF));
	        buff.append("0123456789ABCDEF".charAt(b & 0xF));
	    }
	    return buff.toString();
	}

There are other ways, too.

-- 
Eric Sosman
esosman@comcast-dot-net.invalid

[toc] | [prev] | [next] | [standalone]


#24484

Fromrossum <rossum48@coldmail.com>
Date2013-06-20 14:09 +0100
Message-ID<9hv5s85cul11v42sfop0388joag6mu6t4e@4ax.com>
In reply to#24481
On Thu, 20 Jun 2013 14:03:21 +0200, Laura Schmidt <ls@mailinator.com>
wrote:

>Hi,
>
>I try to convert a byte array to a hex string like this:
>
>  private static String hex_encode (byte [] val)
>  {
>   BigInteger b = new BigInteger(val);
>
>   String t = b.toString(16);
>
>   return (t);
>  }
>
>For a long byte array it returns a "negative" hex string, i. e. starting 
>with a "-" sign.
>
>But I want just the bytes in the array converted to hex representation, 
>each one ranging from "00" to "FF". There should be no minus sign then.
>
>Can you help?
>Thanks!
>
>Laura
This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
that it expects the byte array in two's complement representation, so
a leading 1 bit is interpreted as a negative number.  You need a
different constructor:

  public BigInteger(int signum, byte[] magnitude)

This lets you set the sign separately.

rossum

[toc] | [prev] | [next] | [standalone]


#24485

FromLaura Schmidt <ls@mailinator.com>
Date2013-06-20 15:32 +0200
Message-ID<kpv0a9$gio$1@news.albasani.net>
In reply to#24484
On 06/20/2013 03:09 PM, rossum wrote:

> This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
> that it expects the byte array in two's complement representation, so
> a leading 1 bit is interpreted as a negative number.  You need a
> different constructor:
>
>    public BigInteger(int signum, byte[] magnitude)

You are right, sorry.

Now I get a hex string without sign. But now the decode method does not 
return the original bytes anymore:

  private byte [] hex_decode (String val)
  {
   BigInteger b = new BigInteger (val,16);
   byte [] t = b.toByteArray();

   return (t);
  }

There is no other constructor for byte arrays.
And I don't really understand why it doesn't return the original byte array.

Laura

[toc] | [prev] | [next] | [standalone]


#24486

Fromrossum <rossum48@coldmail.com>
Date2013-06-20 15:44 +0100
Message-ID<9q46s811lpb47jnqv1mtct778r7nnelju4@4ax.com>
In reply to#24485
On Thu, 20 Jun 2013 15:32:56 +0200, Laura Schmidt <ls@mailinator.com>
wrote:

>On 06/20/2013 03:09 PM, rossum wrote:
>
>> This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
>> that it expects the byte array in two's complement representation, so
>> a leading 1 bit is interpreted as a negative number.  You need a
>> different constructor:
>>
>>    public BigInteger(int signum, byte[] magnitude)
>
>You are right, sorry.
>
>Now I get a hex string without sign. But now the decode method does not 
>return the original bytes anymore:
>
>  private byte [] hex_decode (String val)
>  {
>   BigInteger b = new BigInteger (val,16);
>   byte [] t = b.toByteArray();
>
>   return (t);
>  }
>
>There is no other constructor for byte arrays.
>And I don't really understand why it doesn't return the original byte array.
>
>Laura
Again, you need to look at the Javadoc.  That tells you toByteArray()
returns the two's complement representation of the BigInt.

Either convert the two's complement or write your own hex_decode(), it
isn't that difficult.

As a minor point, you should follow the Java naming conventions:
hexEncode() and hexDecode().  Underscores are more C++ than Java.

rossum

[toc] | [prev] | [next] | [standalone]


#24488

Fromlipska the kat <"nospam at neversurrender dot co dot uk">
Date2013-06-20 19:22 +0100
Message-ID<Y4WdncJquPfF1V7MnZ2dnUVZ8uednZ2d@bt.com>
In reply to#24485
On 20/06/13 14:32, Laura Schmidt wrote:
> On 06/20/2013 03:09 PM, rossum wrote:
>
>> This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
>> that it expects the byte array in two's complement representation, so
>> a leading 1 bit is interpreted as a negative number.  You need a
>> different constructor:
>>
>>    public BigInteger(int signum, byte[] magnitude)
>
> You are right, sorry.
>
> Now I get a hex string without sign. But now the decode method does not
> return the original bytes anymore:
>
>   private byte [] hex_decode (String val)
>   {
>    BigInteger b = new BigInteger (val,16);
>    byte [] t = b.toByteArray();
>
>    return (t);
>   }
>
> There is no other constructor for byte arrays.
> And I don't really understand why it doesn't return the original byte
> array.

I'm not sure what all this twos compliment stuff is about
twos compliment is just a number representation scheme
There should be no need to 'convert' anything

Anyway

The following program works with the following observation

If the most significant byte is positive e.g >= 1 && <= 127 or 0x7F
the conversion works both ways

If the most significant byte is negative or 0 e.g <= 0 && >= -128 or 
0x80 then the conversion works with one proviso

The contract for BigInteger#toByteArray() contains the following text

"The array will contain the minimum number of bytes required to 
represent this BigInteger, including at least one sign bit"

so, if the MSB is negative there will be an additional byte in the MSG 
position after calling toByteArray set to 0 which indicates that the 
following is a positive number, if the MSB is positive there is no need 
for an additional byte as the first bit in the MSB is 0 thereby marking 
the following number as positive ... interesting, never seen this 
before... apart from that it seems to work.

Try changing the byte variable a to a positive number to see the 
difference.


<code compiles='yes'>

import java.math.BigInteger;

public class Converter {
	
	private static void printBytes(byte[] val){
		for(byte b : val){
			System.out.print(b);
			System.out.print(' ');
		}
		System.out.print("\n");
	}
	
    	
	private static String hexEncode (byte[] val){
		BigInteger b = new BigInteger(1, val);
		String t = b.toString(16);
		return t;
		//Just Say No to this :-)
		//return new BigInteger(1, val).toString(16);
	}
	
	private static byte[] hexDecode (String val){
		BigInteger b = new BigInteger (val, 16);
		byte[] t = b.toByteArray();
		return t;
	}

	public static void main(String[] args) {
		byte a = -1;   //0xFF
		byte b = 127;  //0x7F
		byte c = -128; //0x80
		byte d = 64;   //0x40
		byte e = 16;   //0x10
		byte f = 99;   //0x5A
		
		byte[] val = {a, b, c, d, e, f};
		
		printBytes(val);
		
		String encoded = hexEncode(val);
		
		System.out.println(encoded);
		
		byte[] decoded = hexDecode(encoded);
		
		printBytes(decoded);
		
         	encoded = hexEncode(decoded);
		
		System.out.println(encoded);

	}

}

</code>

lipska

-- 
Lipska the Kat©: Troll hunter, sandbox destroyer
and farscape dreamer of Aeryn Sun

[toc] | [prev] | [next] | [standalone]


#24489

Frommarkspace <markspace@nospam.nospam>
Date2013-06-20 11:56 -0700
Message-ID<kpvivk$elg$1@dont-email.me>
In reply to#24488
On 6/20/2013 11:22 AM, lipska the kat wrote:

>      public static void main(String[] args) {
>          byte a = -1;   //0xFF
>          byte b = 127;  //0x7F
>          byte c = -128; //0x80
>          byte d = 64;   //0x40
>          byte e = 16;   //0x10
>          byte f = 99;   //0x5A


Laura, if you're still reading, please note especially this part of the 
sample program.  If you want to know if your idea is going to work, you 
have to test it.  This list of test vectors is excellent, and also an 
excellent example of how to unit test a method.

You'll need to do testing like this not only for yourself, now, to 
assure you that your method really works, but also for posterity, by 
which I mean also yourself, but three months from now when you have 
completely forgotten the details of any method you implement today.

(Or if you're like me, posterity means about two weeks from now.  Or less.)

[toc] | [prev] | [next] | [standalone]


#24490

Fromlipska the kat <"nospam at neversurrender dot co dot uk">
Date2013-06-20 20:43 +0100
Message-ID<RZadnZyCl53qxl7MnZ2dnUVZ8nCdnZ2d@bt.com>
In reply to#24489
On 20/06/13 19:56, markspace wrote:
> On 6/20/2013 11:22 AM, lipska the kat wrote:
>
>>      public static void main(String[] args) {
>>          byte a = -1;   //0xFF
>>          byte b = 127;  //0x7F
>>          byte c = -128; //0x80
>>          byte d = 64;   //0x40
>>          byte e = 16;   //0x10
>>          byte f = 99;   //0x5A
>
>
> Laura, if you're still reading, please note especially this part of the
> sample program.  If you want to know if your idea is going to work, you
> have to test it.  This list of test vectors is excellent, and also an
> excellent example of how to unit test a method.
>
> You'll need to do testing like this not only for yourself, now, to
> assure you that your method really works, but also for posterity, by
> which I mean also yourself, but three months from now when you have
> completely forgotten the details of any method you implement today.
>
> (Or if you're like me, posterity means about two weeks from now.  Or less.)
>

Heh, two weeks sounds about right.

lipska

-- 
Lipska the Kat©: Troll hunter, sandbox destroyer
and farscape dreamer of Aeryn Sun

[toc] | [prev] | [next] | [standalone]


#24492

FromLew <lewbloch@gmail.com>
Date2013-06-20 13:39 -0700
Message-ID<66032944-f695-4060-a48b-03633fcd9c91@googlegroups.com>
In reply to#24488
lipska the kat wrote:
> Laura Schmidt wrote:
>> rossum wrote:
>>> This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
>>> that it expects the byte array in two's complement representation, so
>>> a leading 1 bit is interpreted as a negative number.  You need a
>>> different constructor:
>>>
>>>    public BigInteger(int signum, byte[] magnitude)
>>
>> You are right, sorry.
>>
>> Now I get a hex string without sign. But now the decode method does not
>> return the original bytes anymore:
>>
>>   private byte [] hex_decode (String val)
>>   {
>>    BigInteger b = new BigInteger (val,16);
>>    byte [] t = b.toByteArray();
>>
>>    return (t);
>>   }
>>
>> There is no other constructor for byte arrays.
>> And I don't really understand why it doesn't return the original byte
>> array.
> 
> I'm not sure what all this twos compliment stuff is about

That's spelled "two's-complement".

> twos compliment is just a number representation scheme

And the purpose of that constructor is just to convert a representation 
in that scheme to the correct number.

> There should be no need to 'convert' anything

If there isn't, then don't use that constructor.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#24495

Fromlipska the kat <"nospam at neversurrender dot co dot uk">
Date2013-06-21 08:17 +0100
Message-ID<A_mdnQ7xaL6-Y17MnZ2dnUVZ8lednZ2d@bt.com>
In reply to#24492
On 20/06/13 21:39, Lew wrote:
> lipska the kat wrote:
>> Laura Schmidt wrote:
>>> rossum wrote:
>>>> This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
>>>> that it expects the byte array in two's complement representation, so
>>>> a leading 1 bit is interpreted as a negative number.  You need a
>>>> different constructor:
>>>>
>>>>     public BigInteger(int signum, byte[] magnitude)
>>>
>>> You are right, sorry.
>>>
>>> Now I get a hex string without sign. But now the decode method does not
>>> return the original bytes anymore:
>>>
>>>    private byte [] hex_decode (String val)
>>>    {
>>>     BigInteger b = new BigInteger (val,16);
>>>     byte [] t = b.toByteArray();
>>>
>>>     return (t);
>>>    }
>>>
>>> There is no other constructor for byte arrays.
>>> And I don't really understand why it doesn't return the original byte
>>> array.
>>
>> I'm not sure what all this twos compliment stuff is about
>
> That's spelled "two's-complement".
>
>> twos compliment is just a number representation scheme
>
> And the purpose of that constructor is just to convert a representation
> in that scheme to the correct number.
>
>> There should be no need to 'convert' anything
>
> If there isn't, then don't use that constructor.

How incredibly interesting.

lipska

-- 
Lipska the Kat©: Troll hunter, sandbox destroyer
and farscape dreamer of Aeryn Sun

[toc] | [prev] | [next] | [standalone]


#24536

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-06-26 22:16 -0400
Message-ID<51cba07b$0$32111$14726298@news.sunsite.dk>
In reply to#24488
On 6/20/2013 2:22 PM, lipska the kat wrote:
> On 20/06/13 14:32, Laura Schmidt wrote:
>> On 06/20/2013 03:09 PM, rossum wrote:
>>> This is a case of RTFM.  The Javadocs for BigInteger(byte[]) tell you
>>> that it expects the byte array in two's complement representation, so
>>> a leading 1 bit is interpreted as a negative number.  You need a
>>> different constructor:
>>>
>>>    public BigInteger(int signum, byte[] magnitude)
>>
>> You are right, sorry.
>>
>> Now I get a hex string without sign. But now the decode method does not
>> return the original bytes anymore:
>>
>>   private byte [] hex_decode (String val)
>>   {
>>    BigInteger b = new BigInteger (val,16);
>>    byte [] t = b.toByteArray();
>>
>>    return (t);
>>   }
>>
>> There is no other constructor for byte arrays.
>> And I don't really understand why it doesn't return the original byte
>> array.
>
> I'm not sure what all this twos compliment stuff is about
> twos compliment is just a number representation scheme
> There should be no need to 'convert' anything

> The following program works with the following observation
>
> If the most significant byte is positive e.g >= 1 && <= 127 or 0x7F
> the conversion works both ways
>
> If the most significant byte is negative or 0 e.g <= 0 && >= -128 or
> 0x80 then the conversion works with one proviso
>
> The contract for BigInteger#toByteArray() contains the following text
>
> "The array will contain the minimum number of bytes required to
> represent this BigInteger, including at least one sign bit"
>
> so, if the MSB is negative there will be an additional byte in the MSG
> position after calling toByteArray set to 0 which indicates that the
> following is a positive number, if the MSB is positive there is no need
> for an additional byte as the first bit in the MSB is 0 thereby marking
> the following number as positive ... interesting, never seen this
> before... apart from that it seems to work.

You will also get into problems with leading zero bytes.

Arne

[toc] | [prev] | [next] | [standalone]


#24491

FromJoerg Meier <joergmmeier@arcor.de>
Date2013-06-20 22:09 +0200
Message-ID<16xd6kqk55a7s$.1w2vnmqtc1nx4.dlg@40tude.net>
In reply to#24481
On Thu, 20 Jun 2013 14:03:21 +0200, Laura Schmidt wrote:

> I try to convert a byte array to a hex string like this:

>   private static String hex_encode (byte [] val)
>   {
>    BigInteger b = new BigInteger(val);
> 
>    String t = b.toString(16);
> 
>    return (t);
>   }

> For a long byte array it returns a "negative" hex string, i. e. starting 
> with a "-" sign.

> But I want just the bytes in the array converted to hex representation, 
> each one ranging from "00" to "FF". There should be no minus sign then.

> Can you help?

If you are not married to reinventing the wheel, such as by a homework
assignment or whatever, you could always use:

DatatypeConverter.printHexBinary(val);

instead.

Liebe Gruesse,
		Joerg

-- 
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.

[toc] | [prev] | [next] | [standalone]


#24503

FromRoedy Green <see_website@mindprod.com.invalid>
Date2013-06-21 14:51 -0700
Message-ID<2lf9s8dkji8grt44qenen8k731pghra5rf@4ax.com>
In reply to#24481
On Thu, 20 Jun 2013 14:03:21 +0200, Laura Schmidt <ls@mailinator.com>
wrote, quoted or indirectly quoted someone who said :

Here is a low level direct way to convert byte[] to a hex String. It
should be quite a bit faster than using high level routines.

/**
 * Fast convert a byte array to a hex string
 * with possible leading zero.
 * @param b array of bytes to convert to string
 * @return hex representation, two chars per byte.
 */
public static String toHexString ( byte[] b )
   {
   StringBuilder sb = new StringBuilder( b.length * 2 );
   for ( int i=0; i<b.length; i++ )
      {
      // look up high nibble char
      sb.append( hexChar [( b[i] & 0xf0 ) >>> 4] );

      // look up low nibble char
      sb.append( hexChar [b[i] & 0x0f] );
      }
   return sb.toString();
   }

/**
 * table to convert a nibble to a hex char.
 */
static char[] hexChar = {
   '0' , '1' , '2' , '3' ,
   '4' , '5' , '6' , '7' ,
   '8' , '9' , 'a' , 'b' ,
   'c' , 'd' , 'e' , 'f'};
-- 
Roedy Green Canadian Mind Products http://mindprod.com
Getting information off the Internet is 
like taking a drink from a fire hydrant.
~ Mitch Kapor 1950-11-01

[toc] | [prev] | [next] | [standalone]


#24504

FromJoerg Meier <joergmmeier@arcor.de>
Date2013-06-22 00:26 +0200
Message-ID<qdnytcrvwob4.14l9nuassw2g5$.dlg@40tude.net>
In reply to#24503
On Fri, 21 Jun 2013 14:51:09 -0700, Roedy Green wrote:

> On Thu, 20 Jun 2013 14:03:21 +0200, Laura Schmidt <ls@mailinator.com>
> wrote, quoted or indirectly quoted someone who said :

> Here is a low level direct way to convert byte[] to a hex String. It
> should be quite a bit faster than using high level routines.

> /**
>  * Fast convert a byte array to a hex string
>  * with possible leading zero.
>  * @param b array of bytes to convert to string
>  * @return hex representation, two chars per byte.
>  */
> public static String toHexString ( byte[] b )
>    {
>    StringBuilder sb = new StringBuilder( b.length * 2 );
>    for ( int i=0; i<b.length; i++ )
>       {
>       // look up high nibble char
>       sb.append( hexChar [( b[i] & 0xf0 ) >>> 4] );
> 
>       // look up low nibble char
>       sb.append( hexChar [b[i] & 0x0f] );
>       }
>    return sb.toString();
>    }

Note that this is pretty much a copy and paste version of the converter
that already comes with the JRE:

from javax.xml.bind.DatatypeConverterImpl:

public String printHexBinary(byte[] data) {
         StringBuilder r = new StringBuilder(data.length * 2);
         for (byte b : data) {
             r.append(hexCode[(b >> 4) & 0xF]);
             r.append(hexCode[(b & 0xF)]);
         }
         return r.toString();
     }
     
For a reason I was unable to discern it was actually a teensy bit slower
than the Oracle implementation.

Liebe Gruesse,
		Joerg

-- 
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.

[toc] | [prev] | [next] | [standalone]


#24517

FromRoedy Green <see_website@mindprod.com.invalid>
Date2013-06-23 08:49 -0700
Message-ID<c26es85kfu6a95accpbcfg0o4ufojodhne@4ax.com>
In reply to#24504
On Sat, 22 Jun 2013 00:26:49 +0200, Joerg Meier <joergmmeier@arcor.de>
wrote, quoted or indirectly quoted someone who said :

>For a reason I was unable to discern it was actually a teensy bit slower
>than the Oracle implementation.

I forgot to make my static array final.  That might have done it.
The corrected version is posted at http://mindprod.com/jgloss/hex.html

How did you think to look for such a method in that package by that
name?
-- 
Roedy Green Canadian Mind Products http://mindprod.com
Getting information off the Internet is 
like taking a drink from a fire hydrant.
~ Mitch Kapor 1950-11-01

[toc] | [prev] | [next] | [standalone]


#24520

FromJoerg Meier <joergmmeier@arcor.de>
Date2013-06-23 22:37 +0200
Message-ID<nqk78kxi0fk2.yhz4meaf84ys$.dlg@40tude.net>
In reply to#24517
On Sun, 23 Jun 2013 08:49:12 -0700, Roedy Green wrote:

> On Sat, 22 Jun 2013 00:26:49 +0200, Joerg Meier <joergmmeier@arcor.de>
> wrote, quoted or indirectly quoted someone who said :
>>For a reason I was unable to discern it was actually a teensy bit slower
>>than the Oracle implementation.
> I forgot to make my static array final.  That might have done it.
> The corrected version is posted at http://mindprod.com/jgloss/hex.html

It has not made any difference in my test case, but I will readily admit
that I only jotted down a very primitive one, so it's entirely possible
that the issue was on my end. Either way, it was only around 5-10%, so I
didn't bother to look into it too much.

> How did you think to look for such a method in that package by that
> name?

I must admit that I don't recall how I first came upon it, but ever since I
did, I retained to memory that Java "has that", and the few times I needed
it, I just used Google until I found "the one in the JRE". It's not the
most obvious of places, I agree.

Liebe Gruesse,
		Joerg

-- 
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.

[toc] | [prev] | [next] | [standalone]


#24519

FromRoedy Green <see_website@mindprod.com.invalid>
Date2013-06-23 12:40 -0700
Message-ID<9pjes8t6m7echl5a8m3bioeji2j6tjv0rb@4ax.com>
In reply to#24504
On Sat, 22 Jun 2013 00:26:49 +0200, Joerg Meier <joergmmeier@arcor.de>
wrote, quoted or indirectly quoted someone who said :

>For a reason I was unable to discern it was actually a teensy bit slower
>than the Oracle implementation.

The code looks almost identical. Probably the difference was caused by
different "warmup" times before starting to measure.  You have to give
it time to apply the hotspot.
-- 
Roedy Green Canadian Mind Products http://mindprod.com
Getting information off the Internet is 
like taking a drink from a fire hydrant.
~ Mitch Kapor 1950-11-01

[toc] | [prev] | [next] | [standalone]


#24521

FromJoerg Meier <joergmmeier@arcor.de>
Date2013-06-23 22:41 +0200
Message-ID<151xqy4tau28d$.nq94zzouq9ya$.dlg@40tude.net>
In reply to#24519
On Sun, 23 Jun 2013 12:40:29 -0700, Roedy Green wrote:

> On Sat, 22 Jun 2013 00:26:49 +0200, Joerg Meier <joergmmeier@arcor.de>
> wrote, quoted or indirectly quoted someone who said :
>>For a reason I was unable to discern it was actually a teensy bit slower
>>than the Oracle implementation.
> The code looks almost identical. Probably the difference was caused by
> different "warmup" times before starting to measure.  You have to give
> it time to apply the hotspot.

I looped both versions multiple times, and while times varied, yours was
consistently slower. But, like I said in my other post, not nearly by
enough as to prefer one over the other.

For what it's worth, I just noticed that my code is from OpenJDK, but I
tested the code from Oracle. Is there still a difference with these
classes, or are they identical now ? I'm not near my dev PC with the Oracle
JDK/sources right now.

Liebe Gruesse,
		Joerg

-- 
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.

[toc] | [prev] | [next] | [standalone]


#24535

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-06-26 22:12 -0400
Message-ID<51cb9f8f$0$32111$14726298@news.sunsite.dk>
In reply to#24481
On 6/20/2013 8:03 AM, Laura Schmidt wrote:
> I try to convert a byte array to a hex string like this:
>
>   private static String hex_encode (byte [] val)
>   {
>    BigInteger b = new BigInteger(val);
>
>    String t = b.toString(16);
>
>    return (t);
>   }
>
> For a long byte array it returns a "negative" hex string, i. e. starting
> with a "-" sign.
>
> But I want just the bytes in the array converted to hex representation,
> each one ranging from "00" to "FF". There should be no minus sign then.

You have already received several working solutions.

I will strongly recommend you drop the idea about using
BigInteger for this.

It becomes extremely tricky to get it right - you have already
found the sign problem - next problem will be the leading zero
problem.

See below for coding examples (and I am not even sure that I got the
BigInteger hack correct).

Arne

====

import java.math.BigInteger;
import java.util.Arrays;

import javax.xml.bind.DatatypeConverter;

public class ToHex {
	private static void test(byte[] ba, ByteArrayHex cvt) {
		String s = cvt.encode(ba);
		System.out.println(s);
		byte[] ba2 = cvt.decode(s);
		if(ba2.length != ba.length) {
			System.out.println("Length does not match: " + ba2.length + " != " + 
ba.length);
		}
		for(int i = 0; i < Math.min(ba2.length, ba.length); i++) {
			if(ba2[i] != ba[i]) {
				System.out.println("Byte " + i + " does not match: " + ba2[i] + " != 
" + ba[i]);
			}
		}
	}
	private static void testAll(byte[] ba) {
		test(ba, new ManualWithInteger());
		test(ba, new ManualWithString());
		test(ba, new ManualWithCalc());
		test(ba, new JAXBTrick());
		test(ba, new BigIntegerHack());
	}
	public static void main(String[] args) {
		testAll(new byte[] { 1, 2, 3, 4, 5 });
		testAll(new byte[] { -1, -2, -3, -4, -5 });
		testAll(new byte[] { 0, 0, 0 });
	}
}

interface ByteArrayHex {
	public String encode(byte[] ba);
	public byte[] decode(String s);
}

class ManualWithInteger implements ByteArrayHex {
	public String encode(byte[] ba) {
		StringBuilder sb = new StringBuilder();
	    for(int i = 0; i < ba.length; i++) {
	    	sb.append(Integer.toHexString((ba[i] >> 4) & 0x0F));
	    	sb.append(Integer.toHexString(ba[i] & 0x0F));
	    }
	    return sb.toString();
	}
	public byte[] decode(String s) {
	    int n = s.length() / 2;
	    byte[] res = new byte[n];
	    for(int i = 0; i < n; i++) {
	        res[i] = (byte)(Integer.parseInt(s.substring(2 * i, 2 * i + 2), 
16));
	    }
	    return res;
	}
}

class ManualWithString implements ByteArrayHex {
	private static final String HEX = "0123456789abcdef";
	public String encode(byte[] ba) {
		StringBuilder sb = new StringBuilder();
	    for(int i = 0; i < ba.length; i++) {
	    	sb.append(HEX.charAt((ba[i] >> 4) & 0x0F));
	    	sb.append(HEX.charAt(ba[i] & 0x0F));
	    }
	    return sb.toString();
	}
	public byte[] decode(String s) {
	    int n = s.length() / 2;
	    byte[] res = new byte[n];
	    for(int i = 0; i < n; i++) {
	        res[i] = (byte)(HEX.indexOf(s.charAt(2 * i)) << 4 | 
HEX.indexOf(s.charAt(2 * i + 1)));
	    }
	    return res;
	}
}

class ManualWithCalc implements ByteArrayHex {
	private char encode(int v) {
		if(v < 10) {
			return (char)('0' + v);
		} else if(v < 16) {
			return (char)('a' + v - 10);
		} else {
			throw new RuntimeException("Invalid hex value");
		}
	}
	public String encode(byte[] ba) {
		StringBuilder sb = new StringBuilder();
	    for(int i = 0; i < ba.length; i++) {
	    	sb.append(encode((ba[i] >> 4) & 0x0F));
	    	sb.append(encode(ba[i] & 0x0F));
	    }
	    return sb.toString();
	}
	private int decode(char c) {
		if('0' <= c && c <= '9') {
			return c - '0';
		} else if('a' <= c && c <= 'f') {
			return c - 'a' + 10;
		} else {
			throw new RuntimeException("Invalid hex value");
		}
	}
	public byte[] decode(String s) {
	    int n = s.length() / 2;
	    byte[] res = new byte[n];
	    for(int i = 0; i < n; i++) {
	        res[i] = (byte)(decode(s.charAt(2 * i)) << 4 | 
decode(s.charAt(2 * i + 1)));
	    }
	    return res;
	}
}

class JAXBTrick implements ByteArrayHex {
	public String encode(byte[] ba) {
		return DatatypeConverter.printHexBinary(ba);
	}
	public byte[] decode(String s) {
		return DatatypeConverter.parseHexBinary(s);
	}
}

class BigIntegerHack implements ByteArrayHex {
	private String leftPad(String s, char c, int totlen) {
		StringBuilder sb = new StringBuilder();
		for(int i = s.length(); i < totlen; i++) sb.append(c);
		sb.append(s);
		return sb.toString();
	}
	private byte[] leftTrim(byte[] ba, int len) {
		return len < ba.length ? Arrays.copyOfRange(ba, ba.length - len, 
ba.length) : ba;
	}
	private byte[] leftPad(byte[] ba, byte b, int totlen) {
		byte[] res = new byte[totlen];
		int padlen = totlen - ba.length;
		for(int i = 0; i < padlen; i++) res[i] = b;
		System.arraycopy(ba, 0, res, padlen, ba.length);
		return res;
	}
	public String encode(byte[] ba) {
		BigInteger bi = new BigInteger(1, ba);
		String s = bi.toString(16);
		return leftPad(s, '0', ba.length * 2);
	}
	public byte[] decode(String s) {
		BigInteger bi = new BigInteger(s, 16);
		return leftPad(leftTrim(bi.toByteArray(), s.length() / 2), (byte)0, 
s.length() / 2);
	}
}



[toc] | [prev] | [next] | [standalone]


#24537

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-06-26 22:20 -0400
Message-ID<51cba166$0$32107$14726298@news.sunsite.dk>
In reply to#24535
On 6/26/2013 10:12 PM, Arne Vajhøj wrote:
> On 6/20/2013 8:03 AM, Laura Schmidt wrote:
>> I try to convert a byte array to a hex string like this:
>>
>>   private static String hex_encode (byte [] val)
>>   {
>>    BigInteger b = new BigInteger(val);
>>
>>    String t = b.toString(16);
>>
>>    return (t);
>>   }
>>
>> For a long byte array it returns a "negative" hex string, i. e. starting
>> with a "-" sign.
>>
>> But I want just the bytes in the array converted to hex representation,
>> each one ranging from "00" to "FF". There should be no minus sign then.
>
> You have already received several working solutions.
>
> I will strongly recommend you drop the idea about using
> BigInteger for this.
>
> It becomes extremely tricky to get it right - you have already
> found the sign problem - next problem will be the leading zero
> problem.

One of the problems is that toString(radix) and toHexString()
are not the same method.

Demo:

public class SimpleHex {
	public static void main(String[] args) {
		for(int i = -1; i <= 1; i++) {
			System.out.println(Integer.toString(i, 16));
			System.out.println(Integer.toHexString(i));
		}
	}
}


Arne

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web