使用 Kotlin 中的标准库生成字符串的 MD5 哈希值?
我已经尝试过下面提到的代码
import java.math.BigInteger
import java.security.MessageDigest
fun md5(input:String): String {
val md = MessageDigest.getInstance("MD5")
return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
}
这是最好的方法还是哪个?
使用
java.security.MessageDigest
是最简单的方法
import java.math.BigInteger
import java.security.MessageDigest
fun md5(input:String): String {
val md = MessageDigest.getInstance("MD5")
return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
}
一般来说,哈希(摘要)函数将字节数组作为输入并生成字节数组作为输出。因此,要散列 一个字符串,首先需要将其转换为字节数组。执行此操作的常见方法是将字符串编码为
UTF-8
字节数组:string.toByteArray(UTF_8)
将字节数组显示为字符串的常见方法是将各个字节转换为其十六进制值并将它们连接起来。这是一个扩展函数,可以做到这一点:
fun ByteArray.toHex() = joinToString(separator = "") { byte -> "%02x".format(byte) }
生成长度为 16 的字节数组。转换为十六进制时,它由长度为 32 的字符串表示。 完整代码如下所示:
import java.security.MessageDigest
import kotlin.text.Charsets.UTF_8
fun ByteArray.toHex() = joinToString(separator = "") { byte -> "%02x".format(byte) }
fun hashString(str: String, algorithm: String): ByteArray =
MessageDigest.getInstance(algorithm).digest(str.toByteArray(UTF_8))
fun main() {
hashString("Hello, world!", "MD5").toHex()
.also { check(it == "6cd3556deb0da54bca060b4c39479839") }
hashString("", "MD5").toHex()
.also { check(it == "d41d8cd98f00b204e9800998ecf8427e") }
}
,MD5 具有“众所周知的弱点”,这使得它不适合许多用例。替代方案包括 SHA 系列哈希函数。以下是如何在字符串上应用 SHA-256
:
fun main() {
hashString("Hello, world!", "SHA-256").toHex()
.also { check(it == "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3") }
hashString("", "SHA-256").toHex()
.also { check(it == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") }
}
我建议使用 Apache commons 编解码器 1.15 版本
import org.apache.commons.codec.digest.DigestUtils
fun main(args: Array<String>) {
println(DigestUtils.md5Hex("Hello world!"))
}
import java.math.BigInteger
import java.security.MessageDigest
fun main(args: Array<String>) {
println(md5Hash("Hello, world!"))
}
fun md5Hash(str: String): String {
val md = MessageDigest.getInstance("MD5")
val bigInt = BigInteger(1, md.digest(str.toByteArray(Charsets.UTF_8)))
return String.format("%032x", bigInt)
}