sha256sum and (new BigInteger(1, MD.digest())).toString(16) notlisting exactly the same ...

A

Albretch Mueller

I justnoticed that Linux's sha256sum of a binary file
~
$ sha256sum -b *.bin
035dfc8af407ad305c9b6ad9c265efb57cc283684a37e7b94853c7aa76919ad0
*p69.bin
~
and java sha-256 signatures were not the same because (new BigInteger
(1, MD.digest())).toString(16) discards the leading 0's producing
~
35dfc8af407ad305c9b6ad9c265efb57cc283684a37e7b94853c7aa76919ad0
~
How do you deal with these subtle differences without a hack? Is
there a way to instruct BigInteger to keep leading 0's? Or anyother
way to do that?
 
A

alexandre_paterson

 I justnoticed that Linux's sha256sum of a binary file
~
$ sha256sum -b *.bin
*p69.bin
~
and java sha-256 signatures were not the same because (new BigInteger
(1, MD.digest())).toString(16) discards the leading 0's producing
~
35dfc8af407ad305c9b6ad9c265efb57cc283684a37e7b94853c7aa76919ad0
~
 How do you deal with these subtle differences without a hack? Is
there a way to instruct BigInteger to keep leading 0's? Or anyother
way to do that?

Left padding. It's not a hack. It's not hard to write a left pad
method yourself.

Jakarta commons's StringUtils has a leftPad method.

Or you logical OR your BigInteger with a bigint that has its
257 bit set then you discard the char at 0.

Both would work and are really simple.
 
A

alexandre_paterson

Left padding.  It's not a hack.  It's not hard to write a left pad
method yourself.

Replying to myself, taking a quick look at the BigInteger method
there's this:

zeros[63] =
"000000000000000000000000000000000000000000000000000000000000000";

Which screams padding :)

Googling-on-"padding"-is-your-friend :)
 
A

Albretch Mueller

Left padding. It's not a hack.
~
well, I see. I could go " ...".endsWith() and then make sure that the
left side matches all 0's or I may use the DecimalFormat class ...
~
I just thought BigInteger or some Base16 method in java which does
not assume you are converting a number, would do
~
By the way. Where does java stash its Base{16, 32, 64} libraries? is
there any way to easily/reliably access them, or will I have to use
the jakarta commons libraries?
~
lbrtchx
 
M

Mike Schilling

Albretch said:
~
well, I see. I could go " ...".endsWith() and then make sure that
the
left side matches all 0's or I may use the DecimalFormat class ...

Or simply pad with 2 * array.length - string.length() zeros
 
E

Eric Sosman

I justnoticed that Linux's sha256sum of a binary file
~
$ sha256sum -b *.bin
035dfc8af407ad305c9b6ad9c265efb57cc283684a37e7b94853c7aa76919ad0
*p69.bin
~
and java sha-256 signatures were not the same because (new BigInteger
(1, MD.digest())).toString(16) discards the leading 0's producing
~
35dfc8af407ad305c9b6ad9c265efb57cc283684a37e7b94853c7aa76919ad0
~
How do you deal with these subtle differences without a hack? Is
there a way to instruct BigInteger to keep leading 0's? Or anyother
way to do that?

How many leading zeroes should a BigInteger keep? (Hint:
A BigInteger can have as many as 2147483647 value bits, or
536870912 hexadecimal digits. How many of those should toString()
produce?)

In other words, your problem is not with "retaining leading
zeroes," but with padding a number to a specified width. At a
brief glance, it seems the problem is self-inflicted: It's the
conversion from byte[] to BigInteger that "loses" the information
about width, not the conversion from BigInteger to String.
 
L

Lew

Albretch said:
By the way. Where does java [sic] stash its Base{16, 32, 64} libraries? is
there any way to easily/reliably access them, or will I have to use
the jakarta [sic] commons libraries?

What do you mean by "its Base{16, 32, 64} libraries"? What functionality do
you seek?

Since number base is strictly a display artifact, you find Java's support in
various conversion methods:

<http://java.sun.com/javase/6/docs/api/java/math/BigInteger.html#BigInteger(java.lang.String, int)>
<http://java.sun.com/javase/6/docs/api/java/math/BigInteger.html#toString(int)>
<http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#valueOf(java.lang.String, int)>
<http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#toString(int, int)>
<http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#toHexString(int)>
<http://java.sun.com/javase/6/docs/a...format(java.lang.String, java.lang.Object...)>

to name a few.
 
M

markspace

Lew said:
Albretch said:
By the way. Where does java [sic] stash its Base{16, 32, 64}
libraries? is
there any way to easily/reliably access them, or will I have to use
the jakarta [sic] commons libraries?

What do you mean by "its Base{16, 32, 64} libraries"? What
functionality do you seek?


I think he means the utilities provided by Jakarta Commons.

<http://commons.apache.org/codec/>
 
T

Tom Anderson

By the way. Where does java stash its Base{16, 32, 64} libraries? is
there any way to easily/reliably access them, or will I have to use the
jakarta commons libraries?

You can get base64 from javax.mail:

http://www.rgagnon.com/javadetails/java-0598.html

You can get short kinds of base16 from Integer et al, but you'll have to
roll your own for longer data.

I don't know of any base32 support. Nor, tragically, base85, which is of
course the best encoding.

tom
 
M

markspace

Albretch said:
~
I just thought BigInteger or some Base16 method in java which does
not assume you are converting a number, would do


I wouldn't use either left padding or DecimalFormat. What happens when
you get a negative number in BigInteger? I don't think this is easy to
deal with.

I also wouldn't use Jakarta Commons' codec just for this one function.
It's easy enough to roll your own. Lightly tested:


private static final String hexDigigs = "0123456789abcdef";
public static String asHexString( byte[] bytes ) {
StringBuilder sb = new StringBuilder();
for( byte b : bytes ) {
sb.append( hexDigigs.charAt( (b & 0xFF) >>> 4 ) );
sb.append( hexDigigs.charAt( b & 0xF ) );
}
return sb.toString();
}
 
M

Mike Schilling

markspace said:
I wouldn't use either left padding or DecimalFormat. What happens
when you get a negative number in BigInteger?

You don't. The constructor the OP used says "this is a positive
number".
 
A

Albretch Mueller

// __ http://www.rgagnon.com/javadetails/java-0596.html

The simple way
public static String getHexString(byte[] b) throws Exception {
String result = "";
for (int i=0; i < b.length; i++) {
result +=
Integer.toString( ( b & 0xff ) + 0x100, 16).substring
( 1 );
}
return result;
}

A faster way
import java.io.UnsupportedEncodingException;

public class StringUtils {

static final byte[] HEX_CHAR_TABLE = {
(byte)'0', (byte)'1', (byte)'2', (byte)'3',
(byte)'4', (byte)'5', (byte)'6', (byte)'7',
(byte)'8', (byte)'9', (byte)'a', (byte)'b',
(byte)'c', (byte)'d', (byte)'e', (byte)'f'
};

public static String getHexString(byte[] raw)
throws UnsupportedEncodingException
{
byte[] hex = new byte[2 * raw.length];
int index = 0;

for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
return new String(hex, "ASCII");
}

public static void main(String args[]) throws Exception{
byte[] byteArray = {
(byte)255, (byte)254, (byte)253,
(byte)252, (byte)251, (byte)250
};

System.out.println(StringUtils.getHexString(byteArray));

/*
* output :
* fffefdfcfbfa
*/

}
}
 
L

Lew

Albretch said:
// __ http://www.rgagnon.com/javadetails/java-0596.html

The simple way
public static String getHexString(byte[] b) throws Exception {
String result = "";
for (int i=0; i < b.length; i++) {
result +=
Integer.toString( ( b & 0xff ) + 0x100, 16).substring
( 1 );
}
return result;
}

A faster way
import java.io.UnsupportedEncodingException;

public class StringUtils {

static final byte[] HEX_CHAR_TABLE = {
(byte)'0', (byte)'1', (byte)'2', (byte)'3',
(byte)'4', (byte)'5', (byte)'6', (byte)'7',
(byte)'8', (byte)'9', (byte)'a', (byte)'b',
(byte)'c', (byte)'d', (byte)'e', (byte)'f'
};

public static String getHexString(byte[] raw)
throws UnsupportedEncodingException
{
byte[] hex = new byte[2 * raw.length];
int index = 0;

for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
return new String(hex, "ASCII");
} // ...
}


You can avoid encoding and some obfuscation by making the table 'char []' and
using 'StringBuilder hex' instead of a 'byte[]', otherwise the same algorithm.
Or the table can be "0123456789ABCDEF" and the StringBuilder can append
charAt()s. No more specious exception, either.

static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw )
{
if ( raw == null ) // or could just let throw NPE
{
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw )
{
hex.append( HEXES.charAt( (b & 0xF0) >> 4 )
.append( HEXES.charAt( (b & 0x0F) );
}
return hex.toString();
}
 
R

Real Gagnon

Lew said:
static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw )
{
if ( raw == null ) // or could just let throw NPE
{
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw )
{
hex.append( HEXES.charAt( (b & 0xF0) >> 4 )
.append( HEXES.charAt( (b & 0x0F) );
}
return hex.toString();
}

Your suggestion about the usage of a StringBuilder to get rid of the
exception declaration is a good one but your code has a 2 missing ")".

hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));

Bye.
 
L

Lew

Lew said:
  static final String HEXES = "0123456789ABCDEF";
  public static String getHex( byte [] raw )
  {
    if ( raw == null ) // or could just let throw NPE
    {
      return null;
    }
    final StringBuilder hex = new StringBuilder( 2 * raw.length );
    for ( final byte b : raw )
    {
      hex.append( HEXES.charAt( (b & 0xF0) >> 4 )
         .append( HEXES.charAt( (b & 0x0F) );
    }
    return hex.toString();
  }

Real said:
Your suggestion about the usage of a StringBuilder to get rid of the
exception declaration is a good one but your code has a 2 missing ")".

      hex.append(HEXES.charAt((b & 0xF0) >> 4))
         .append(HEXES.charAt((b & 0x0F)));

Oopsie.

That's the risk of posting code one hasn't compiled. When I do
occasionally compile code before posting, I enclose it in the (fake
XML) tag "<sscce>" or explicitly mention that I compiled the code
first, otherwise typos and bugs are left for the reader to discover.

Good catch.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,815
Latest member
treekmostly22

Latest Threads

Top