5

I am trying to compare the SHA-256 hash values of the same file with Python and Java. However, in some instances, the Python hash value has leading zeros, whereas the Java version does not. For instance, hashing somefile.txt in both programs yields:

Python: 000c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890

Java : c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890

Is it safe to simply remove leading 0's and compare or is there an implementation which does not produce the leading zeros?

Python Code

def sha256sum(filename): h = hashlib.sha256() b = bytearray(128*1024) mv = memoryview(b) with open(filename, 'rb', buffering=0) as f: for n in iter(lambda : f.readinto(mv), 0): h.update(mv[:n]) return h.hexdigest() print(sha256sum('/somepath/somefile.txt')) # 000c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890 

Java Code

public static String calculateSHA256(File updateFile) { MessageDigest digest; try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { Log.e(TAG, "Exception while getting digest", e); return null; } InputStream is; try { is = new FileInputStream(updateFile); } catch (FileNotFoundException e) { Log.e(TAG, "Exception while getting FileInputStream", e); return null; } byte[] buffer = new byte[8192]; int read; try { while ((read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); } byte[] shaSum = digest.digest(); BigInteger bigInt = new BigInteger(1, shaSum); String output = bigInt.toString(16); return output; } catch (IOException e) { throw new RuntimeException("Unable to process file for SHA256", e); } finally { try { is.close(); } catch (IOException e) { Log.e(TAG, "Exception on closing SHA256 input stream", e); } } } Log.i("Output", calculateSHA256(somefile)) // I/Output: c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890 
1
  • 2
    It's because you are using BigInteger. I think that it is this that is stripping off leading zeros. Commented Feb 27, 2019 at 14:54

1 Answer 1

8

The BigInteger conversion is ignoring leading zeros in your SHA-256 hash. Instead you should encode byte[] directly. As suggested in this answer you can use String.format():

StringBuilder sb = new StringBuilder(); for (byte b : shaSum) { sb.append(String.format("%02X", b)); } return sb.toString(); 

When encoded as hex string the SHA-256 value has 64 characters, as per wiki example:

SHA256("")

0x e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Sign up to request clarification or add additional context in comments.

2 Comments

Note that the "%02X" format will uppercase the string (see the Javadoc here). Use "%02x" if you want the preserve the lowercase letters.
Thank you for this. Had the exact same issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.