从 C# 到 Android/java 的端口 sha-1 哈希

port sha-1 hash from C# to Android/java

我需要从 C# 移植以下代码

    private string hashcode(string code)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(code);
        byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(bytes);
        return Convert.ToBase64String(inArray);
    }

到 Android 应用程序。我在 Java 中有这个:

private static String hashCode(String userCode) {
    String hashSha1;
    MessageDigest digest = null;
    try {
        digest = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    digest.reset();
    byte[] data = digest.digest(userCode.getBytes());
    return Base64.encodeToString(data, Base64.DEFAULT);
}

唉,这段代码不会产生相同的结果。找出原因是一个非常疯狂的追逐。

我可以在 Android 中做什么来获得相同的哈希值?

这是将 userCode 字符串转换为字节的 C# 代码:

byte[] bytes = Encoding.Unicode.GetBytes(code);

而 Java 代码只是:

userCode.getBytes()

这意味着在 Java 中您使用的是平台默认编码,在 Android 上是 UTF-8。您应该指定 Encoding.Unicode, which is StandardCharsets.UTF_16LE.

的等效编码

你几乎 永远不会 调用 String(byte[])String.getBytes(),它们都使用平台默认编码。 始终指定要使用的编码。

关于更笼统的观点,您说 "finding out why is a pretty wild goose chase" - 但在这种情况下,解决方案几乎 总是 详细记录转换中的一步一次。你在这里有三个转换:

  • Stringbyte[](将 userCode 编码为二进制数据)
  • MD5 哈希(byte[]byte[]
  • 将哈希编码为 base64

如果您单独执行了每个步骤并记录了结果,您就会发现问题出在第一步。

Android 将 UTF-8 作为默认字符集。请尝试 String.getBytes(Charset charset) using StandardCharsets.UTF_16LE