2010-10-14 3 views
44

Je travaille sur une application Android et j'ai quelques chaînes que je voudrais crypter avant de l'envoyer à une base de données. J'aimerais que quelque chose de sûr, facile à implémenter, produise la même chose chaque fois qu'il a transmis les mêmes données, et de préférence se traduira par une chaîne qui reste une longueur constante, quelle que soit la taille de la chaîne qui lui est transmise. Peut-être que je cherche un hash.Comment hacher une chaîne dans Android?

+1

Un hachage est unidirectionnel, si vous voulez être en mesure de déchiffrer des données que vous ne pouvez pas stocker avec une longueur constante IMHO –

+2

Je sais. C'est pour la validation et je dois juste pouvoir comparer une valeur à une autre, je n'ai pas besoin de la "défaire". Je sais que je n'ai pas dit si j'avais prévu de déchiffrer, alors merci d'avoir répondu. – Jorsher

+1

Aucune infraction, mais le titre de votre question est trompeur –

Répondre

81

Cet extrait Calculons md5 pour une chaîne donnée

public String md5(String s) { 
    try { 
     // Create MD5 Hash 
     MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); 
     digest.update(s.getBytes()); 
     byte messageDigest[] = digest.digest(); 

     // Create Hex String 
     StringBuffer hexString = new StringBuffer(); 
     for (int i=0; i<messageDigest.length; i++) 
      hexString.append(Integer.toHexString(0xFF & messageDigest[i])); 
     return hexString.toString(); 

    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return ""; 
} 

Source: http://www.androidsnippets.com/snippets/52/index.html

Espérons que cela est utile pour vous

+2

MD5, afaik, n'est pas considéré comme réversible. En règle générale, vous devez hacher quelque chose, généralement un mot de passe ou quelque chose de similaire, puis, pour vérifier le mot de passe, vous exécutez le même chiffrement et comparez les résultats à ce qui est stocké. – Jorsher

+27

Ce code ne fonctionne pas correctement. Certains caractères "0" sont manquants dans la chaîne générée. Je ne sais pas pourquoi, mais c'est le cas. –

+5

Il y a une condition spéciale quand ce code échoue. Lorsque le premier des deux nombres hexadécimaux est zéro. Ce code est meilleur: http://stackoverflow.com/a/6565597/221135 – Jaec

7
private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 

public static String byteArrayToHex(byte[] array) { 
    String s = ""; 
    for (int i = 0; i < array.length; ++i) { 
     int di = (array[i] + 256) & 0xFF; // Make it unsigned 
     s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF]; 
    } 
    return s; 
} 

public static String digest(String s, String algorithm) { 
    MessageDigest m = null; 
    try { 
     m = MessageDigest.getInstance(algorithm); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
     return s; 
    } 

    m.update(s.getBytes(), 0, s.length()); 
    return byteArrayToHex(m.digest()); 
} 

public static String md5(String s) { 
    return digest(s, "MD5"); 
} 
+2

oui 100 %% travail j'ai eu au-dessus de la fucntion toute cause avec 0 désactiver mais cette solution à 3 fonctions me donne la solution exacte que j'ai eue avec .net md5 – CoronaPintu

+0

Voici votre solution avec le support UTF-8: http: // stackoverflow.com/a/19589939/537694 – Climbatize

60

Cette fonction ci-dessus de (http://www.androidsnippets.org/snippets/52/index.html) est défectueux. Si l'un des chiffres du messageDigest n'est pas une valeur hexadécimale à deux caractères (par exemple 0x09), il ne fonctionne pas correctement car il ne contient pas de 0. Si vous cherchez autour de vous, vous trouverez cette fonction et les plaintes à ce sujet ne fonctionne pas. Voici un meilleur found in the comment section of this page, que je légèrement modifié:

public static String md5(String s) 
{ 
    MessageDigest digest; 
    try 
    { 
     digest = MessageDigest.getInstance("MD5"); 
     digest.update(s.getBytes(Charset.forName("US-ASCII")),0,s.length()); 
     byte[] magnitude = digest.digest(); 
     BigInteger bi = new BigInteger(1, magnitude); 
     String hash = String.format("%0" + (magnitude.length << 1) + "x", bi); 
     return hash; 
    } 
    catch (NoSuchAlgorithmException e) 
    { 
     e.printStackTrace(); 
    } 
    return ""; 
} 
+2

et beaucoup plus agréable à lire :) – Janusz

+6

Celui-ci a aussi un problème. Essayez d'encoder q4m'x68n6_YDB4ty8VC4 &} wqBtn^68W , il donne c70bb931f03b75af1591f261eb77d0b alors que le bon doit être 0c70bb931f03b75af1591f261eb77d0b First 0 disappers. –

+2

pas cher il cause problème il va jeter 0 j'ai essayé dans .net et java cette fucntion rejeter 0 – CoronaPintu

5

La réponse est au-dessus correcte près de 100%. Il va échouer avec unicode.

MessageDigest digest; 
    try { 
     digest = MessageDigest.getInstance("MD5"); 
     byte utf8_bytes[] = tag_xml.getBytes(); 
     digest.update(utf8_bytes,0,utf8_bytes.length); 
     hash = new BigInteger(1, digest.digest()).toString(16); 
    } 
    catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 

Vous avez besoin de la longueur du tableau d'octets et non de la chaîne.

+0

ce qui est ** tag_xml * * ici?? essayer ** q4m'x68n6_YDB4ty8VC4 &} wqBtn^68W ** avec le code ci-dessus, le résultat est ** ** c70bb931f03b75af1591f261eb77d0b au lieu de ** 0c70bb931f03b75af1591f261eb77d0b ** comme mentionné par @Sertap Bilal dans le commentaire de la réponse ci-dessus cette répondre. –

3

solution de Donut dans une seule fonction:

private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 

private static String md5(String s) 
{ 
    MessageDigest digest; 
    try 
    { 
     digest = MessageDigest.getInstance("MD5"); 
     digest.update(s.getBytes(), 0, s.length()); 
     byte[] bytes = digest.digest(); 

     String hash = ""; 
     for (int i = 0; i < bytes.length; ++i) 
     { 
      int di = (bytes[i] + 256) & 0xFF; 
      hash = hash + hextable[(di >> 4) & 0xF] + hextable[di & 0xF]; 
     } 

     return hash; 
    } 
    catch (NoSuchAlgorithmException e) 
    { 
    } 

    return ""; 
} 
1
MessageDigest md = MessageDigest.getInstance("MD5"); 
md.update('yourstring'); 
byte[] digest = md.digest(); 
StringBuffer sb = new StringBuffer(); 
for (byte b : digest) { 
    sb.append(String.format("%02x", (0xFF & b))); 
} 

Il est tard pour l'auteur, mais avant cela, je reçois Integer.toHexString(0xff&b), ces bandes menant de la chaîne 0s hexagonale. Ça me fait mal depuis longtemps. J'espère utile pour certains gars.

19

méthode ne fonctionne pas:

public static String md5(String s) { 
    try { 
     // Create MD5 Hash 
     MessageDigest digest = java.security.MessageDigest 
       .getInstance("MD5"); 
     digest.update(s.getBytes()); 
     byte messageDigest[] = digest.digest(); 

     // Create Hex String 
     StringBuffer hexString = new StringBuffer(); 
     for (int i = 0; i < messageDigest.length; i++) 
      hexString.append(Integer.toHexString(0xFF & messageDigest[i])); 
     return hexString.toString(); 

    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return ""; 
} 

résultat - 1865e62e7129927f6e4cd9bff104f0 (longueur 30)

méthode de travail:

public static final String md5(final String toEncrypt) { 
    try { 
     final MessageDigest digest = MessageDigest.getInstance("md5"); 
     digest.update(toEncrypt.getBytes()); 
     final byte[] bytes = digest.digest(); 
     final StringBuilder sb = new StringBuilder(); 
     for (int i = 0; i < bytes.length; i++) { 
      sb.append(String.format("%02X", bytes[i])); 
     } 
     return sb.toString().toLowerCase(); 
    } catch (Exception exc) { 
     return ""; // Impossibru! 
    } 
} 

résultat - 1865e62e7129927f6e4c0d9bff1004f0 (longueur 32)

+0

+1 pour la méthode de travail :) Cela fonctionne. – anivaler

5

Avec @Donut solution, avec des caractères codés UTF-8 (par exemple: é) vous devez utilisez getBytes("UTF-8"). Voici ma correction de la méthode de digestion:

private static char[] hextable = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 


public static String byteArrayToHex(byte[] array) { 
    String s = ""; 
    for (int i = 0; i < array.length; ++i) { 
     int di = (array[i] + 256) & 0xFF; // Make it unsigned 
     s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF]; 
    } 
    return s; 
} 

public static String digest(String s, String algorithm) { 
    MessageDigest m = null; 
    try { 
     m = MessageDigest.getInstance(algorithm); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
     return s; 
    } 

    try { 
     m.update(s.getBytes("UTF-8")); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
     m.update(s.getBytes()); 
    } 
    return byteArrayToHex(m.digest()); 
} 

public static String md5(String s) { 
    return digest(s, "MD5"); 
} 
2

Ce qui suit a fonctionné pour moi sur Android sans troncature de Infront de tout 0:

MessageDigest md = null; 
String digest = null; 
    try { 
     md = MessageDigest.getInstance("MD5"); 

     byte[] hash = md.digest(myStringToEncode.getBytes("UTF-8")); //converting byte array to Hexadecimal String 
     StringBuilder sb = new StringBuilder(2*hash.length); 

     for(byte b : hash){ 
      sb.append(String.format("%02x", b&0xff)); 
     } 

     digest = sb.toString(); 

    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 

return digest; 
0

si vous utilisez la goyave:

public String generateMd5(String input) { 
    HashFunction hf = Hashing.md5(); 
    Hasher hasher = hf.newHasher(); 

    HashCode hc = hasher.putString(input, StandardCharsets.UTF_8).hash(); 

    return hc.toString(); 
} 
0

Si vous n'aviez pas de contraintes de sécurité et vous vouliez juste convertir String en un int unique. Je l'écris parce que c'est ce que j'ai cherché et atteint ici.

String my_key 
int my_key.hashCode() 

si vous avez jusqu'à 10 caractères, il sera même unique Voir aussi https://stackoverflow.com/a/17583653/1984636

1

Ce ne manque pas '0'

public static String md5(String string) { 
     if (TextUtils.isEmpty(string)) { 
      return ""; 
     } 
     MessageDigest md5 = null; 
     try { 
      md5 = MessageDigest.getInstance("MD5"); 
      byte[] bytes = md5.digest(string.getBytes()); 
      String result = ""; 
      for (byte b : bytes) { 
       String temp = Integer.toHexString(b & 0xff); 
       if (temp.length() == 1) { 
        temp = "0" + temp; 
       } 
       result += temp; 
      } 
      return result; 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } 
     return ""; 
    } 
Questions connexes