如何在Android中散列字符串?

如何在Android中散列字符串?,android,hash,sha1,Android,Hash,Sha1,在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%0

在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]
        ];  
}
现在我需要同样的安卓系统,但无法找到如何做到这一点。我一直在寻找这个例子:
但这并没有给我和iPhone一样的结果。有人能给我指一下正确的方向吗?

你不需要和身份证。您只需使用简单的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);
    }
}
import java.io.UnsupportedEncodingException;
导入java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
公共类AeSimpleSHA1{
专用静态字符串convertToHex(字节[]数据){
StringBuilder buf=新的StringBuilder();
for(字节b:数据){
int半字节=(b>>>4)&0x0F;
int two_halfs=0;
做{
追加((0一个更简单的SHA-1方法:(根据评论员的建议更新,也使用了一个更高效的字节->字符串算法)

String-sha1Hash(String-to-hash)
{
字符串hash=null;
尝试
{
MessageDigest=MessageDigest.getInstance(“SHA-1”);
byte[]bytes=toHash.getBytes(“UTF-8”);
更新(字节,0,字节,长度);
字节=摘要。摘要();
//这比循环和String.formating()快约55倍
hash=bytesToHex(字节);
}
捕获(无算法异常)
{
e、 printStackTrace();
}
捕获(不支持的编码异常e)
{
e、 printStackTrace();
}
返回散列;
}
// http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
最终受保护的静态字符[]hexArray=“0123456789ABCDEF”.toCharArray();
公共静态字符串bytesToHex(字节[]字节)
{
char[]hexChars=新字符[bytes.length*2];
对于(int j=0;j>>4];
hexChars[j*2+1]=hexArray[v&0x0F];
}
返回新字符串(hexChars);
}

您正在寻找的方法不是特定于Android的,而是一般的Java。您正在寻找(
导入Java.security.MessageDigest

可以看到
sha512(String s)
方法的实现,对SHA-1散列的更改将第71行更改为:

MessageDigest md = MessageDigest.getInstance("SHA-1");

Android附带Apache的Commons编解码器,或者您将其作为依赖项添加。然后执行以下操作:

String myHexHash = DigestUtils.shaHex(myFancyInput);
这是Android 4默认使用的旧方法。DigestUtils的新版本带来了shaHex()方法的所有风格,如sha256Hex(),还使用不同的参数类型重载这些方法

如果你可以侥幸逃脱,而且不必重新发明轮子:

final HashCode hashCode = Hashing.sha1().hashString(yourValue, Charset.defaultCharset());
然后,您可以将散列值作为
字节[]
、int
、long获取


没有包装,没有恶作剧。如果你决定使用SHA-1以外的东西,番石榴还支持sha256、SHA 512和一些我从未听说过的东西,如adler32和Murruird 3。

完全基于@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;
    }
}

下面是获取SHA加密字符串的Kotlin版本

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()
    }
}

它最初发布在这里:

感谢您的回答!convertToHex()我使用的是错误的。您的代码运行良好。Greate..非常感谢您为什么使用iso-8559-1编码而不是UTF-8?除非您需要与某些现有应用程序兼容,否则没有什么理由使用此类传统编码。正如下面提到的,text.length()不正确,因为它不会返回字节数。您需要使用getBytes返回的数组长度。而且,是的,它实际上可能不应该是iso-8859。Can“md”是否在Android上为空?如果sha1字符串应该以0开头,则0将被忽略。因此,在某些情况下,此方法返回错误的sha-1编码字符串。警告:如果要哈希“1122”,则此方法无效,它以0Correct开头!更新了解决此问题的答案。感谢捕获这些人。由于代码当前为空,它只返回一个原始字符串的十六进制版本,没有哈希。需要在某处调用digest.digest()。使用默认编码(
somestring.GetBytes()
)将提供与平台相关的哈希。不太好。使用固定编码,最好是UTF-8。重点不是显示如何格式化哈希,而是显示如何创建哈希。注意:使用“%02x”如果你想避免大写。太棒了,我正在分享我的完整实现:正如其他答案所建议的,你应该使用
clearString.getBytes(“UTF-8”)
为了安全起见。我在我的Android应用程序中实现了这段代码,效果非常好。感谢分享。我真的很喜欢这个答案,因为它非常适合Android,而且不需要我再次检查so代码的安全漏洞:p
final HashCode hashCode = Hashing.sha1().hashString(yourValue, Charset.defaultCharset());
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;
    }
}
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()
    }
}