在Objective C中,我一直使用以下代码来散列字符串:
-(NSString *) sha1:(NSString*)stringToHash {
const char *cStr = [stringToHash UTF8String];
unsigned char result[20];
CC_SHA1( cStr, strlen(cStr), result );
return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15],
result[16], result[17], result[18], result[19]
];
}
现在我需要Android的相同功能,但无法知道如何操作。我一直在寻找这样的例子:Make SHA1 encryption on Android? 但这并没有给我与iPhone相同的结果。有人能指出我正确的方向吗?
答案 0 :(得分:152)
你不需要andorid。你可以用简单的java来做。
您是否尝试过一个简单的Java示例,看看它是否返回正确的sha1。
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class AeSimpleSHA1 {
private static String convertToHex(byte[] data) {
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0F;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}
public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] textBytes = text.getBytes("iso-8859-1");
md.update(textBytes, 0, textBytes.length);
byte[] sha1hash = md.digest();
return convertToHex(sha1hash);
}
}
还要分享您的预期sha1应该是什么。也许ObjectC做错了。
答案 1 :(得分:35)
更简单的SHA-1方法:( 根据评论者的建议更新,也使用更高效的字节 - >字符串算法)
String sha1Hash( String toHash )
{
String hash = null;
try
{
MessageDigest digest = MessageDigest.getInstance( "SHA-1" );
byte[] bytes = toHash.getBytes("UTF-8");
digest.update(bytes, 0, bytes.length);
bytes = digest.digest();
// This is ~55x faster than looping and String.formating()
hash = bytesToHex( bytes );
}
catch( NoSuchAlgorithmException e )
{
e.printStackTrace();
}
catch( UnsupportedEncodingException e )
{
e.printStackTrace();
}
return hash;
}
// http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex( byte[] bytes )
{
char[] hexChars = new char[ bytes.length * 2 ];
for( int j = 0; j < bytes.length; j++ )
{
int v = bytes[ j ] & 0xFF;
hexChars[ j * 2 ] = hexArray[ v >>> 4 ];
hexChars[ j * 2 + 1 ] = hexArray[ v & 0x0F ];
}
return new String( hexChars );
}
答案 2 :(得分:27)
如果你可以逃脱using Guava it is by far the simplest way to do it,而你不必重新发明轮子:
final HashCode hashCode = Hashing.sha1().hashString(yourValue, Charset.defaultCharset());
然后,您可以获取散列值并将其作为byte[]
,int
或long
。
没有包装尝试捕获,没有恶作剧。如果你决定使用除SHA-1以外的东西,Guava还支持sha256,sha 512,以及一些我从未听说过像adler32和murmur3那样的东西。
答案 3 :(得分:15)
final MessageDigest digest = MessageDigest.getInstance("SHA-1");
result = digest.digest(stringToHash.getBytes("UTF-8"));
// Another way to construct HEX, my previous post was only the method like your solution
StringBuilder sb = new StringBuilder();
for (byte b : result) // This is your byte[] result..
{
sb.append(String.format("%02X", b));
}
String messageDigest = sb.toString();
答案 4 :(得分:14)
完全基于@ Whymarrh的答案,这是我的实现,测试和工作正常,没有依赖:
public static String getSha1Hex(String clearString)
{
try
{
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
messageDigest.update(clearString.getBytes("UTF-8"));
byte[] bytes = messageDigest.digest();
StringBuilder buffer = new StringBuilder();
for (byte b : bytes)
{
buffer.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return buffer.toString();
}
catch (Exception ignored)
{
ignored.printStackTrace();
return null;
}
}
答案 5 :(得分:8)
Android附带Apache的Commons Codec - 或者您将其添加为依赖项。然后做:
String myHexHash = DigestUtils.shaHex(myFancyInput);
这是默认使用Android 4时旧的弃用方法。新版本的DigestUtils带来了所有shaHex()方法,如sha256Hex(),并且还使用不同的参数类型重载方法。
答案 6 :(得分:2)
您正在寻找的方法并非特定于Android,而是针对Java。您正在寻找MessageDigest(import java.security.MessageDigest
)。
可以看到sha512(String s)
方法的实现here,SHA-1哈希的更改将第71行更改为:
MessageDigest md = MessageDigest.getInstance("SHA-1");
答案 7 :(得分:0)
这里是Kotlin版本,用于获取SHA加密字符串。
import java.security.MessageDigest
object HashUtils {
fun sha512(input: String) = hashString("SHA-512", input)
fun sha256(input: String) = hashString("SHA-256", input)
fun sha1(input: String) = hashString("SHA-1", input)
/**
* Supported algorithms on Android:
*
* Algorithm Supported API Levels
* MD5 1+
* SHA-1 1+
* SHA-224 1-8,22+
* SHA-256 1+
* SHA-384 1+
* SHA-512 1+
*/
private fun hashString(type: String, input: String): String {
val HEX_CHARS = "0123456789ABCDEF"
val bytes = MessageDigest
.getInstance(type)
.digest(input.toByteArray())
val result = StringBuilder(bytes.size * 2)
bytes.forEach {
val i = it.toInt()
result.append(HEX_CHARS[i shr 4 and 0x0f])
result.append(HEX_CHARS[i and 0x0f])
}
return result.toString()
}
}
答案 8 :(得分:-18)
String.format("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15],
result[16], result[17], result[18], result[19]);