Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    Md5 in Java

    Sto facendo un piccolo sistema p2p per un progetto dell'università.
    Ho pensato di utilizzare md5 sia per avere un'impronta di file da usare come "chiave" nelle richieste di file ad un client, sia come verifica del corretto download del file.

    Avevo trovato su questo forum una implementazione e senza pensarci troppo su l'ho usata.. se non che mi sono accorto che è molto lenta (praticamente con file sopra i100kb le attese diventano lunghe.. sul mega siamo ad un'attesa apparentemente infinita).

    L'implementazione è questa:


    codice:
    import java.security.*;
    import java.io.*;
    
    public class Md5
    {
    	private String hash;
    	
    	private String hex(byte[] array)
    	{
    		StringBuffer sb = new StringBuffer();
    		for (int i = 0; i < array.length; i++)
    		{
    			sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).toLowerCase().substring(1,3));
    		}
    		return sb.toString();
    	}
      
    	public Md5 (String message)
    	{
    		try
    		{
    			MessageDigest md = MessageDigest.getInstance("MD5");
    			hash = hex (md.digest(message.getBytes("CP1252")));
    		}
    		catch (NoSuchAlgorithmException e) 
    		{
    			e.printStackTrace();
    		}
    		catch (UnsupportedEncodingException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	public String getHash()
    	{
      		return hash;
    	}
    }
    ho aggiunto solo il metodo getHash() per evitare di accedere alla variabile di classe dall'esterno come faceva chi l'ha postata sul forum.

    Bene... adesso mi sono messo alla ricerca di un'implementazione più veloce e ho trovato in un altro post questo link:
    http://www.pierotofy.it/pages/sorgenti/browse/14628/
    provando il codice si vede che è infinitamente più veloce.. ma restituisce l'md5 sotto forma di array di byte..

    morale:
    l'md5 di un file che contiene solo "ciao" è
    6e6bc4e49dd477ebc98ef4046c067b5f
    secondo la classe "lenta", e
    [B@8814e9
    secondo quella veloce

    Adesso.. non sono un espertone di Java.. praticamente è la prima esperienza che vada oltre la didattica essenziale, ma non riesco a capire se sia possibile ottenere una stringa come quella data dal primo algoritmo, ma con il sistema usato dal secondo algoritmo. A guardare la documentazione delle classi utilizzate da quest'ultimo parrebbe di no.. ma mi affido a voi.

    Ovviamente ben accette segnalazioni di altre implementazioni veloci.. purchè il risultato sia una vera e propria stringa, come per la prima classe.

    Grazie

  2. #2
    Utente di HTML.it L'avatar di nether
    Registrato dal
    Dec 2006
    Messaggi
    376
    guarda i costruttori della classe String: ce ne sono un milione che vogliono come parametro un array di byte
    http://java.sun.com/j2se/1.5.0/docs/...ng/String.html

  3. #3
    Originariamente inviato da nether
    guarda i costruttori della classe String: ce ne sono un milione che vogliono come parametro un array di byte
    http://java.sun.com/j2se/1.5.0/docs/...ng/String.html
    ti ringrazio, ma il risultato(a fronte dello stesso input) è

    nk─õ?ÈwÙ╔Ķ♦l♠{_

    :\\


    il codice dell'algoritmo efficiente è in pratica questo (ovviamente è un metodo della relativa classe, ma è lui che fa tutto):
    codice:
    public static byte[] calcolaHash(String file) throws Exception 
    	{
    		System.out.print("Inizio calcolo hash");
    		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    		System.out.print(".");
    		MessageDigest md = MessageDigest.getInstance("MD5");
    		System.out.print(".");
    		DigestInputStream digestIn = new DigestInputStream(bis, md);
    		System.out.print(".");
    		while(digestIn.read() != -1);
    		byte[] digest = md.digest();
    		System.out.println(". Calcolo terminato!!");
    		return digest;
    	
    	}
    che poi stampo così:
    String hash = new String(calcolaHash(args[1]));
    System.out.println("Hash: "+hash);

  4. #4
    ok.. credo di aver capito...

    l'md5, in byte, è ottenuto sempre così (da una stringa)

    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] md5 = md.digest(stringa.getBytes("CP1252"));


    ed è quello illegibile...

    per trasformarlo in stringa la classe "lenta" usa

    private String hex(byte[] array)
    {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < array.length; i++)
    {
    sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).toLowerCase().substring(1,3));
    }
    return sb.toString();
    }
    ed è qyuesta che rallenta il tutto.


    Morale: non si può avere un md5 più veloce sotto forma di stringa?
    E se lo uso sottoforma di array di byte, che succede? dovrebbe fungere lo stesso immagino..

    mi sa che mi tocca provare

  5. #5
    Utente di HTML.it L'avatar di nether
    Registrato dal
    Dec 2006
    Messaggi
    376
    sinceramente per queste cose ho sempre usato soluzioni gia' pronte...
    quindi se vuoi scrivere qualcosa di tuo mi sa che la sperimentazione rimane il metodo migliore :P

  6. #6
    Originariamente inviato da nether
    sinceramente per queste cose ho sempre usato soluzioni gia' pronte...
    quindi se vuoi scrivere qualcosa di tuo mi sa che la sperimentazione rimane il metodo migliore :P
    guarda.. io ho capito che se usassi l'md5 semplicemente come array di byte non dovrebbero esserci problemi.. lo calcolerebbe in un attimo (è la conversione in stringa che rallenta tutto).

    Nel mio caso però ho già scritto un'applicazione che si aspetta una stringa, e trasmette l'md5 (stringa) in una stringa serializzata che comprende più informazioni (tipo: "nomefile,dimensione,md5") che poi scompongo una volta ricevuta.. ho provato a cambiare al volo tutti i riferimenti da stringa a byte[] ma pare non andare... ci epnserò meglio domani che oggi non ho tempo.. può essere che ho scordato di adattare qualcosa a questa possibile nuova natura dell'md5, oppure è possibile che proprio non riesco a trasmetterla come byte[], almeno non con la logica di trasmissione che ho implementato fin'ora. Domani vedrò, comunque credo sia lì il problema a questo punto, nella trasmissione (almeno nella mia applicaizone). INdagherò.

    per adesso grazie

  7. #7
    mah, è na pecionata che ho scritto in 2 minuti perchè non volevo perderci tempo, ma non mi pare che rallenti molto:

    nella classe che gestisce l'md5 ci metti un array privato del tipo
    codice:
    this.hexKeys = new String[]{"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
    e poi usi un metodo tipo:
    codice:
    	private String toStringmd5(byte[] bs){
    		String res = "";
    		for(byte b : bs){
    			int i = b+128;
    			res += toHex(i);
    		}
    		return res;
    	}
    	
    	private String toHex(int i){
    		int primo = i/16;
    		int secondo = i%16;
    		String a = hexKeys[primo];
    		String b = hexKeys[secondo];
    		return a+b;
    	}
    ripeto, la soluzione è molto piaciona

  8. #8
    ti ringrazio, ma l'ho testato al volo e sembra comunque molto lento

  9. #9
    Guarda, io penso che il problema sia nel calcolo dell'hash, e non nella trasformazione da array di byte in stringa.

    Anche perchè l'md5 sono 32 caratteri (o meglio, 32 byte) quindi la trasformazione da array di byte (che cmq sarà lungo sempre 32) in stringa è un operazione a tempo costante.

    edit: ho visto solo ora i codici che hai postato, quel codice che ti ho postato l'hai usato per trasformare il prodotto del metodo "veloce"? (quello che sta nel link per intenderci)

    Perchè il codice riportato direttamente nel tuo messaggio non mi sembra molto adatto per fare hash da files

  10. #10
    in effetti il tuo ragionamento sul tempo costante non fa una grinza, eppure togliendo la chiamata al metodo "hex", anche la classe lenta diventa veloce...

    comunque il tuo codice l'ho provato sulla prima (quella lenta) al posto della sua "hex", domani lo proverò sulla seconda e ti farò sapere.. però mi sconforta quanto ho detto appena sopra, cioè il fatto che la lentezza non sembri comunque imputabile all'algoritmo in se, quanto alla trasformazione in stringa esadecimale

    in ognin cas, qualunque sarà l'esito domani, ti ringrazio

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.