Java 如何在Android中散列字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3934331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to hash a string in Android?
提问by Jorsher
I am working on an Android app and have a couple strings that I would like to encrypt before sending to a database. I'd like something that's secure, easy to implement, will generate the same thing every time it's passed the same data, and preferably will result in a string that stays a constant length no matter how large the string being passed to it is. Maybe I'm looking for a hash.
我正在开发一个 Android 应用程序,并且有几个字符串,我想在发送到数据库之前对其进行加密。我想要一些安全,易于实现的东西,每次传递相同的数据时都会生成相同的东西,并且最好会导致字符串保持恒定长度,无论传递给它的字符串有多大。也许我正在寻找一个哈希。
采纳答案by Antonio
This snippet calculate md5 for any given string
此代码段计算任何给定字符串的 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 "";
}
Source: http://www.androidsnippets.com/snippets/52/index.html
来源:http: //www.androidsnippets.com/snippets/52/index.html
Hope this is useful for you
希望这对你有用
回答by Donut
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");
}
回答by Craig B
That function above from (http://www.androidsnippets.org/snippets/52/index.html) is flawed. If one of the digits in the messageDigest is not a two character hex value (i.e. 0x09), it doesn't work properly because it doesn't pad with a 0. If you search around you'll find that function and complaints about it not working. Here a better one found in the comment section of this page, which I slightly modified:
上面来自 ( 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 "";
}
回答by Sandstone
The answer above is almost 100% correct. It will fail with unicode.
上面的答案几乎 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();
}
Need the length from the byte array not the string.
需要字节数组的长度而不是字符串。
回答by Tanya
Donut's solution in a single function:
甜甜圈在单个函数中的解决方案:
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 "";
}
回答by kyon
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)));
}
It's late for the author, but before this, I get Integer.toHexString(0xff&b)
, which strips leading 0s from the hex string. It makes me struggled for a long time. Hope useful for some guys.
作者来晚了,但在此之前,我得到了Integer.toHexString(0xff&b)
,它从十六进制字符串中去除了前导 0。这让我挣扎了很长时间。希望对一些人有用。
回答by Yuriy Lisenkov
not working method:
不工作方法:
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 "";
}
result: 1865e62e7129927f6e4cd9bff104f0
(length 30)
结果:(1865e62e7129927f6e4cd9bff104f0
长度 30)
working method:
工作方法:
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!
}
}
result: 1865e62e7129927f6e4c0d9bff1004f0
(length 32)
结果:(1865e62e7129927f6e4c0d9bff1004f0
长度 32)
回答by Climbatize
With @Donut solution, with UTF-8 encoded characters (eg: é) you have to use getBytes("UTF-8")
. Here is my correction of the digest method:
使用@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");
}
回答by Chris
The following worked for me on Android without truncating any 0's infront:
以下在 Android 上对我有用,而不会截断任何 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;
回答by zack
if you are using 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();
}