title: Different results with Java's digest versus external utilities
body: <p>I have written a simple Java class to generate the hash values of the Windows Calculator file.  I am using <code>Windows 7 Professional with SP1</code>.  I have tried <code>Java 6.0.29</code> and <code>Java 7.0.03</code>.  Can someone tell me why I am getting different hash values from Java versus (many!) external utilities and/or websites?  Everything external matches with each other, only Java is returning different results.</p>
  
  <pre><code>import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.util.LinkedHashMap;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.zip.CRC32;
  import java.security.DigestInputStream;
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  
  public class Checksum 
  {
      private static int size = 65536;
      private static File calc = new File("C:/Windows/system32/calc.exe");
  
      /*
          C:\Windows\System32\calc.exe (verified via several different utilities)
          ----------------------------
          CRC-32b = 8D8F5F8E
          MD5     = 60B7C0FEAD45F2066E5B805A91F4F0FC
          SHA-1   = 9018A7D6CDBE859A430E8794E73381F77C840BE0
          SHA-256 = 80C10EE5F21F92F89CBC293A59D2FD4C01C7958AACAD15642558DB700943FA22
          SHA-384 = 551186C804C17B4CCDA07FD5FE83A32B48B4D173DAC3262F16489029894FC008A501B50AB9B53158B429031B043043D2
          SHA-512 = 68B9F9C00FC64DF946684CE81A72A2624F0FC07E07C0C8B3DB2FAE8C9C0415BD1B4A03AD7FFA96985AF0CC5E0410F6C5E29A30200EFFF21AB4B01369A3C59B58
  
  
          Results from this class
          -----------------------
          CRC-32  = 967E5DDE
          MD5     = 10E4A1D2132CCB5C6759F038CDB6F3C9
          SHA-1   = 42D36EEB2140441B48287B7CD30B38105986D68F
          SHA-256 = C6A91CBA00BF87CDB064C49ADAAC82255CBEC6FDD48FD21F9B3B96ABF019916B    
      */    
  
      public static void main(String[] args)throws Exception {
          Map&lt;String, String&gt; hashes = getFileHash(calc);
          for (Map.Entry&lt;String, String&gt; entry : hashes.entrySet()) {
              System.out.println(String.format("%-7s = %s", entry.getKey(), entry.getValue()));
          }
      }
  
      private static Map&lt;String, String&gt; getFileHash(File file) throws NoSuchAlgorithmException, IOException {
          Map&lt;String, String&gt; results = new LinkedHashMap&lt;String, String&gt;();
  
          if (file != null &amp;&amp; file.exists()) {
              CRC32 crc32 = new CRC32();
              MessageDigest md5 = MessageDigest.getInstance("MD5");
              MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
              MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
  
              FileInputStream fis = new FileInputStream(file);
              byte data[] = new byte[size];
              int len = 0;
              while ((len = fis.read(data)) != -1) {
                  crc32.update(data, 0, len);
                  md5.update(data, 0, len);
                  sha1.update(data, 0, len);
                  sha256.update(data, 0, len);
              }
              fis.close();
  
              results.put("CRC-32", toHex(crc32.getValue()));
              results.put(md5.getAlgorithm(), toHex(md5.digest()));
              results.put(sha1.getAlgorithm(), toHex(sha1.digest()));
              results.put(sha256.getAlgorithm(), toHex(sha256.digest()));
          }
          return results;
      }
  
      private static String toHex(byte[] bytes) {
          String result = "";
          if (bytes != null) {
              StringBuilder sb = new StringBuilder(bytes.length * 2);
              for (byte element : bytes) {
                  if ((element &amp; 0xff) &lt; 0x10) {
                      sb.append("0");
                  }
                  sb.append(Long.toString(element &amp; 0xff, 16));
              }
              result = sb.toString().toUpperCase();
          }
          return result;
      }
  
      private static String toHex(long value) {
          return Long.toHexString(value).toUpperCase();
      }
  
  }
  </code></pre>