Bri*_*ian 148 java string sha1
我正在尝试用Java创建一个简单的String to SHA1转换器,这就是我所拥有的......
public static String toSHA1(byte[] convertme) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
}
catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new String(md.digest(convertme));
}
Run Code Online (Sandbox Code Playgroud)
当我通过它时toSHA1("password".getBytes())
,我[?a?????%l?3~??.
知道它可能是一个简单的编码修复,如UTF-8,但有人可以告诉我应该做什么来获得我想要的东西是5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
什么?或者我这样做完全错了?
Nis*_*ant 176
更新
您可以使用Apache Commons Codec(版本1.7+)为您完成这项工作.
DigestUtils.sha1Hex(stringToConvertToSHexRepresentation)
感谢@ Jon Onstott提出这个建议.
旧答案
将您的字节数组转换为十六进制字符串.真实的如何告诉你如何.
return byteArrayToHexString(md.digest(convertme))
Run Code Online (Sandbox Code Playgroud)
和(从Real的方法复制)
public static String byteArrayToHexString(byte[] b) {
String result = "";
for (int i=0; i < b.length; i++) {
result +=
Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,使用Base64可以获得更紧凑的表示.Apache Commons Codec API 1.4,有这个很好的实用工具来消除所有的痛苦.请参考这里
pet*_*ejl 66
这是我将字符串转换为sha1的解决方案.它适用于我的Android应用:
private static String encryptPassword(String password)
{
String sha1 = "";
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(password.getBytes("UTF-8"));
sha1 = byteToHex(crypt.digest());
}
catch(NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
}
return sha1;
}
private static String byteToHex(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
Run Code Online (Sandbox Code Playgroud)
Jan*_*fer 53
Hashing.sha1().hashString( "password", Charsets.UTF_8 ).toString()
Run Code Online (Sandbox Code Playgroud)
Joa*_*uer 31
SHA-1(和所有其他散列算法)返回二进制数据.这意味着(在Java中)他们产生了一个byte[]
.这byte
阵并没有表示任何特定的字符,这意味着你不能简单地把它变成一个String
像你这样.
如果你需要a String
,那么你必须以byte[]
一种可以表示为a的方式格式化String
(否则,只需保持byte[]
周围).
表示任意byte[]
可打印字符的两种常用方法是BASE64或简单的十六进制字符串(即每byte
两个十六进制数字表示).看起来你正在尝试生成一个hex-String.
还有另一个陷阱:如果你想获得一个Java的SHA-1 String
,那么你需要将其转换String
为byte[]
第一(如SHA-1的输入是byte[]
也).如果您只是myString.getBytes()
按照自己的方式使用,那么它将使用平台默认编码,因此将依赖于您运行它的环境(例如,它可能会根据您操作系统的语言/区域设置返回不同的数据).
更好的解决方案是指定要用于编码String
-到- byte[]
这样的转换:myString.getBytes("UTF-8")
.选择UTF-8(或代表每个Unicode字符的其他编码)是最安全的选择.
Nik*_*rov 27
这是一个简单的解决方案,可以在将字符串转换为十六进制格式时使用:
private static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(password.getBytes("UTF-8"));
return new BigInteger(1, crypt.digest()).toString(16);
}
Run Code Online (Sandbox Code Playgroud)
DaT*_*oop 25
只需使用apache commons编解码器库.他们有一个名为DigestUtils的实用程序类
无需深入细节.
kaz*_*uar 18
如前所述,使用apache commons编解码器.这也是Spring的推荐(参见Spring doc中的DigestUtils).例如:
DigestUtils.sha1Hex(b);
Run Code Online (Sandbox Code Playgroud)
绝对不会在这里使用最受好评的答案.
由于您需要使用Base64编码,因此无法正确打印。使用Java 8,您可以使用Base64编码器类进行编码。
public static String toSHA1(byte[] convertme) {
md = MessageDigest.getInstance("SHA-1");
return Base64.getEncoder().encodeToString((md.digest(convertme));
}
Run Code Online (Sandbox Code Playgroud)
结果
这将为您提供预期的输出 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
消息摘要被定义为一个函数,它接受原始字节数组并返回原始字节数组(也称为byte[]
)。例如,SHA-1(安全哈希算法 1)的摘要大小为 160 位或 20 字节。原始字节数组通常不能解释为像UTF-8这样的字符编码,因为并非每个顺序中的每个字节都是合法的编码。所以将它们转换为String
:
new String(md.digest(subject), StandardCharsets.UTF_8)\n
Run Code Online (Sandbox Code Playgroud)\n可能会创建一些非法序列或具有指向未定义的Unicode映射的代码指针:
\n[\xef\xbf\xbda\xef\xbf\xbd\xc9\xb9??\xef\xbf\xbd%l\xef\xbf\xbd3~\xef\xbf\xbd\xef\xbf\xbd.\n
Run Code Online (Sandbox Code Playgroud)\n为此,使用了二进制到文本的编码。对于哈希,最常用的是HEX 编码或 Base16。0
基本上,一个字节可以具有从到255
(或-128
到有符号)的值127
,这相当于0x00
-的十六进制表示0xFF
。因此,十六进制将使输出所需的长度加倍,这意味着 20 字节的输出将创建一个 40 个字符长的十六进制字符串,例如:
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\n
Run Code Online (Sandbox Code Playgroud)\n请注意,不需要使用十六进制编码。您还可以使用诸如base64之类的东西。十六进制通常是首选,因为它更容易被人类阅读,并且具有定义的输出长度而不需要填充。
\n您可以仅使用 JDK 功能将字节数组转换为十六进制:
\n[\xef\xbf\xbda\xef\xbf\xbd\xc9\xb9??\xef\xbf\xbd%l\xef\xbf\xbd3~\xef\xbf\xbd\xef\xbf\xbd.\n
Run Code Online (Sandbox Code Playgroud)\n但请注意,这BigInteger
会将给定的字节数组解释为数字而不是字节字符串。这意味着不会输出前导零,并且生成的字符串可能短于 40 个字符。
您现在可以从 Stack Overflow 复制并粘贴未经测试的字节到十六进制方法,或使用大量依赖项,例如Guava。
\n为了找到大多数字节相关问题的首选解决方案,我实现了一个实用程序来处理这些情况:bytes-java (GitHub)
\n要转换您的消息摘要字节数组,您可以这样做
\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\n
Run Code Online (Sandbox Code Playgroud)\n或者你可以只使用内置的哈希功能
\nnew BigInteger(1, token).toString(16)\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
240862 次 |
最近记录: |