J'ai écrit une classe Java simple pour générer les valeurs de hachage du fichier Windows Calculator. J'utilise Windows 7 Professional with SP1
. J'ai essayé Java 6.0.29
et Java 7.0.03
. Quelqu'un peut-il me dire pourquoi j'obtiens des valeurs de hachage différentes de Java par rapport à (beaucoup!) D'utilitaires externes et / ou de sites Web? Tout ce qui est externe correspond, seul Java renvoie des résultats différents.
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<String, String> hashes = getFileHash(calc);
for (Map.Entry<String, String> entry : hashes.entrySet()) {
System.out.println(String.format("%-7s = %s", entry.getKey(), entry.getValue()));
}
}
private static Map<String, String> getFileHash(File file) throws NoSuchAlgorithmException, IOException {
Map<String, String> results = new LinkedHashMap<String, String>();
if (file != null && 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 & 0xff) < 0x10) {
sb.append("0");
}
sb.append(Long.toString(element & 0xff, 16));
}
result = sb.toString().toUpperCase();
}
return result;
}
private static String toHex(long value) {
return Long.toHexString(value).toUpperCase();
}
}
int newElement = ((int) element) & 0xff
et l'utilisez à la place, cela résoudrait-il votre problème?Réponses:
Je l'ai. Le système de fichiers Windows se comporte différemment selon l'architecture de votre processus. Cet article explique tout - en particulier:
Essayez de copier
calc.exe
ailleurs ... puis exécutez à nouveau les mêmes outils. Vous obtiendrez les mêmes résultats que Java. Quelque chose dans le système de fichiers Windows donne aux outils des données différentes de celles qu'ils donnent à Java ... Je suis sûr que cela a quelque chose à voir avec le fait qu'il soit dans le répertoire Windows, et donc probablement traité "différemment".De plus, je l'ai reproduit en C # ... et j'ai découvert que cela dépend de l' architecture du processus que vous exécutez . Voici donc un exemple de programme:
Et voici une session de console (sans bavardage du compilateur):
la source
calc.exe
: 64 bits dansC:\Windows\system32` and 32bit in
C: \ Windows \ SysWOW64`. Pour la compatibilité dans un processus 32 bitsC:\Windows\system32` is mapped to
C: \ Windows \ SysWOW64`. Les processus 64 bits lanceront le calcul 64 bits, les processus 32 bits le calcul 32 bits. Pas étonnant que leurs sommes de contrôle soient différentes. Si vous maintenez le fichier ouvert et regardez avechandles.exe
ou Process Explorer, vous verrez le chemin différent.