Eu escrevi uma classe Java simples para gerar os valores de hash do arquivo da Calculadora do Windows. estou usandoWindows 7 Professional with SP1
. Eu tentei Java 6.0.29
e Java 7.0.03
. Alguém pode me dizer por que estou obtendo valores de hash diferentes do Java versus (muitos!) Utilitários externos e / ou sites? Tudo externo corresponde um ao outro, apenas Java está retornando resultados diferentes.
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
e usar isso, isso resolveria o seu problema?Respostas:
Entendi. O sistema de arquivos do Windows está se comportando de maneira diferente, dependendo da arquitetura do seu processo. Este artigo explica tudo - em particular:
Tente copiar
calc.exe
para outro lugar ... e execute as mesmas ferramentas novamente. Você obterá os mesmos resultados que Java. Algo no sistema de arquivos do Windows está fornecendo dados diferentes para as ferramentas do que no Java ... Tenho certeza de que isso está relacionado ao fato de ele estar no diretório do Windows e, portanto, provavelmente ser tratado de forma "diferente".Além disso, eu o reproduzi em C # ... e descobri que depende da arquitetura do processo que você está executando . Então, aqui está um exemplo de programa:
E aqui está uma sessão de console (menos a conversa do compilador):
fonte
calc.exe
: 64 bits emC:\Windows\system32` and 32bit in
C: \ Windows \ SysWOW64`. Para compatibilidade em um processo de 32 bits,C:\Windows\system32` is mapped to
C: \ Windows \ SysWOW64`. Os processos de 64 bits lançam o calc de 64 bits, os processos de 32 bits o calc de 32 bits. Não é de surpreender que suas somas de verificação sejam diferentes. Se você mantiver o arquivo aberto e procurar comhandles.exe
ou no Process Explorer, verá o caminho diferente.