Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java SHA1 hash probleema

Zmyrgel [07.11.2009 10:33:43]

#

Yritän saada tiedostoille aikaan SHA1 hashit mutta se ei näytä luonnistuvan.
Lähin mihin pääsin oli oikea hash pienille tiedostoille ja OutOfMemory poikkeus isommilta.

Nyt koodi käy isommatkin tiedostot läpi mutta hash arvot ovat edelleen vääriä.
Jos joku hieman auttelisi että pääsen asiassa etenemään.

  private String getHashOfFile(File file) throws IOException, NoSuchAlgorithmException {

	InputStream istream = new BufferedInputStream(new FileInputStream(file));
	//InputStream istream = new FileInputStream(file);

	int buffer_size = 2048;
	MessageDigest md = MessageDigest.getInstance("SHA-1");

	byte[] bytes = new byte[buffer_size];

	// Passes all data in 1 sec and gives incorrect hashes
        // Read in the bytes
        int offset = 0;
        int n = 0;
        while (offset < bytes.length && (n = istream.read(bytes, offset, bytes.length-offset)) >= 0) {
	    md.update(bytes);
            offset += n;
	}

	// Goes through the data but gives wrong hashes
	//while ((numRead = istream.read(bytes)) != -1) {
	//md.update(bytes);
	//bytes = new byte[buffer_size]; // clear buffer to get last bytes correctly?
	//}

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
	 }

	// Get digested hash
	byte[] hash = md.digest();

	// Close the input stream and return bytes
        istream.close();
        return toHex(hash);
    }
}

toHex -metodin tulisi olla ihan kunnossa joten virheen tulisi olla yllä olevassa koodin pätkässä.

Olen tuossa muutamaa netistä löytämääni esimerkkiä mukailla mutta vielä en ole saanut hommaa toimimaan kunnolla.

Metabolix [07.11.2009 11:08:53]

#

Ensimmäinen silmukkasi toimii ilmiselvästi aivan väärin: Tiedostosta luetaan kokonaisuudessaan enintään 2048 tavua, koska se on puskurin koko etkä missään vaiheessa nollaa offset-muuttujaa. Lisäksi päivität hashia joka kerta koko 2048 tavun taulukolla, vaikka olisit lukenut vähemmän dataa ja muuhun kohtaan kuin taulukon alkuun. (Tarkistapa dokumentaatiosta, mitä käyttämäsi read-funktion muoto tekeekään.)

Toinen versio sen sijaan lukee tiedostoa aivan oikein pätkissä, mutta luetusta määrästä riippumatta päivität taas hashia koko 2048 tavun puskurin verran. Uuden puskurin luonti ei ratkaise ongelmaa, koska koko on silti sama. Puskurin käyttämättömällä alueella on nollia (siis tietysti nollatavuja), eli lopputulos on sama kuin jos tiedostossa olisi ylimääräisiä nollia.

Koska datan asettelulla puskurissa ei ole merkitystä, jälkimmäinen lukutapa on oikea. Luettu data alkaa aina puskurin alusta, ja määrä selviää read-funktion paluuarvosta. Hashia pitää päivittää juuri näillä tavuilla, eli pitää käyttää update-funktion versiota, jolle voi antaa käsiteltävän datan alkukohdan ja pituuden taulukossa.

while ((n = istream.read(bytes)) != -1) {
  md.update(bytes, 0, n);
}

Zmyrgel [08.11.2009 13:47:59]

#

Minä kiitän, junamatkan ajan tuon kanssa tappelin kunnes jätin sikseen.
Nyt näyttää pelittävän.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta