Я работаю над Android-приложением и имею пару строк, которые я хотел бы зашифровать перед отправкой в базу данных. Я хотел бы, чтобы что-то, что было безопасным, простым в реализации, будет генерировать то же самое каждый раз, когда оно передало одни и те же данные, и предпочтительно приведет к тому, что строка останется постоянной, независимо от того, насколько велика передаваемая ей строка. Возможно, я ищу хэш.
Как хэш строку в Android?
Ответ 1
Этот фрагмент вычисляет md5 для любой строки
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 "";
}
Источник: http://www.androidsnippets.com/snippets/52/index.html
Надеюсь, это полезно для вас.
Ответ 2
Эта функция выше (http://www.androidsnippets.org/snippets/52/index.html) является ошибочной. Если одна из цифр в messageDigest не является шестнадцатеричным значением в два символа (то есть 0x09), она не работает должным образом, потому что она не заполняется с помощью 0. Если вы будете искать вокруг, вы найдете эту функцию и жалобы на нее не работает. Здесь лучший найден в разделе комментариев этой страницы, который я слегка изменил:
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 "";
}
Ответ 3
не работает метод:
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 "";
}
результат: 1865e62e7129927f6e4cd9bff104f0
(длина 30)
метод работы:
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!
}
}
результат: 1865e62e7129927f6e4c0d9bff1004f0
(длина 32)
Ответ 4
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");
}
Ответ 5
Ответ выше почти на 100% правильный. Он будет работать с 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();
}
Требуется длина из массива байтов, а не строка.
Ответ 6
С решением @Donut с кодированными символами UTF-8 (например: é) вы должны использовать getBytes("UTF-8")
. Вот моя коррекция метода дайджеста:
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");
}
Ответ 7
Решение пончика в одной функции:
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 "";
}
Ответ 8
Следующее работало для меня на Android без усечения любого 0 infront:
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;
Ответ 9
Если у вас не было ограничений безопасности и просто нужно было преобразовать String в уникальный int. Я пишу это, потому что это то, что я искал и достиг здесь.
String my_key
int my_key.hashCode()
если у вас есть до 10 символов, это будет даже уникальным Смотрите также fooobar.com/questions/66772/...
Ответ 10
Это не пропало '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 "";
}
Ответ 11
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)));
}
Поздно для автора, но до этого я получаю Integer.toHexString(0xff&b)
, который разбивает ведущие 0s из шестнадцатеричной строки. Это заставляет меня бороться долгое время. Надеюсь, полезно некоторым парням.
Ответ 12
если вы используете guava:
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();
}