initial commit
This commit is contained in:
109
src/commonMain/kotlin/com/infendro/hash/MD5.kt
Normal file
109
src/commonMain/kotlin/com/infendro/hash/MD5.kt
Normal file
@@ -0,0 +1,109 @@
|
||||
package com.infendro.hash
|
||||
|
||||
import com.infendro.hash.util.ByteOrder.LITTLE_ENDIAN
|
||||
import com.infendro.hash.util.addAll
|
||||
import com.infendro.hash.util.toByteArray
|
||||
import com.infendro.hash.util.toUIntArray
|
||||
|
||||
object MD5 : HashFunction() {
|
||||
private val s = arrayOf(
|
||||
7, 12, 17, 22,
|
||||
7, 12, 17, 22,
|
||||
7, 12, 17, 22,
|
||||
7, 12, 17, 22,
|
||||
5, 9, 14, 20,
|
||||
5, 9, 14, 20,
|
||||
5, 9, 14, 20,
|
||||
5, 9, 14, 20,
|
||||
4, 11, 16, 23,
|
||||
4, 11, 16, 23,
|
||||
4, 11, 16, 23,
|
||||
4, 11, 16, 23,
|
||||
6, 10, 15, 21,
|
||||
6, 10, 15, 21,
|
||||
6, 10, 15, 21,
|
||||
6, 10, 15, 21,
|
||||
)
|
||||
|
||||
private val k = arrayOf(
|
||||
0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU,
|
||||
0xf57c0fafU, 0x4787c62aU, 0xa8304613U, 0xfd469501U,
|
||||
0x698098d8U, 0x8b44f7afU, 0xffff5bb1U, 0x895cd7beU,
|
||||
0x6b901122U, 0xfd987193U, 0xa679438eU, 0x49b40821U,
|
||||
0xf61e2562U, 0xc040b340U, 0x265e5a51U, 0xe9b6c7aaU,
|
||||
0xd62f105dU, 0x02441453U, 0xd8a1e681U, 0xe7d3fbc8U,
|
||||
0x21e1cde6U, 0xc33707d6U, 0xf4d50d87U, 0x455a14edU,
|
||||
0xa9e3e905U, 0xfcefa3f8U, 0x676f02d9U, 0x8d2a4c8aU,
|
||||
0xfffa3942U, 0x8771f681U, 0x6d9d6122U, 0xfde5380cU,
|
||||
0xa4beea44U, 0x4bdecfa9U, 0xf6bb4b60U, 0xbebfbc70U,
|
||||
0x289b7ec6U, 0xeaa127faU, 0xd4ef3085U, 0x04881d05U,
|
||||
0xd9d4d039U, 0xe6db99e5U, 0x1fa27cf8U, 0xc4ac5665U,
|
||||
0xf4292244U, 0x432aff97U, 0xab9423a7U, 0xfc93a039U,
|
||||
0x655b59c3U, 0x8f0ccc92U, 0xffeff47dU, 0x85845dd1U,
|
||||
0x6fa87e4fU, 0xfe2ce6e0U, 0xa3014314U, 0x4e0811a1U,
|
||||
0xf7537e82U, 0xbd3af235U, 0x2ad7d2bbU, 0xeb86d391U,
|
||||
)
|
||||
|
||||
override fun hash(
|
||||
value: ByteArray,
|
||||
): ByteArray {
|
||||
var a0 = 0x67452301U
|
||||
var b0 = 0xefcdab89U
|
||||
var c0 = 0x98badcfeU
|
||||
var d0 = 0x10325476U
|
||||
val ml = value.size.toULong() * 8UL
|
||||
|
||||
val paddedValue = buildList {
|
||||
addAll(value)
|
||||
add(0x80.toByte())
|
||||
while (size % 64 != 56) {
|
||||
add(0x00.toByte())
|
||||
}
|
||||
addAll(ml.toByteArray(LITTLE_ENDIAN))
|
||||
}
|
||||
|
||||
val chunks = paddedValue
|
||||
.chunked(64)
|
||||
for (chunk in chunks) {
|
||||
val w = buildList {
|
||||
addAll(chunk.toUIntArray(LITTLE_ENDIAN))
|
||||
}
|
||||
|
||||
var a = a0
|
||||
var b = b0
|
||||
var c = c0
|
||||
var d = d0
|
||||
|
||||
for (i in 0..<64) {
|
||||
val f = when (i) {
|
||||
in 0..15 -> (b and c) or (b.inv() and d)
|
||||
in 16..31 -> (d and b) or (d.inv() and c)
|
||||
in 32..47 -> b xor c xor d
|
||||
else -> c xor (b or d.inv())
|
||||
}
|
||||
val g = when (i) {
|
||||
in 0..15 -> i
|
||||
in 16..31 -> (5 * i + 1) % 16
|
||||
in 32..47 -> (3 * i + 5) % 16
|
||||
else -> (7 * i) % 16
|
||||
}
|
||||
a = d
|
||||
d = c
|
||||
c = b
|
||||
b += (f + a + k[i] + w[g]).rotateLeft(s[i])
|
||||
}
|
||||
|
||||
a0 += a
|
||||
b0 += b
|
||||
c0 += c
|
||||
d0 += d
|
||||
}
|
||||
|
||||
return byteArrayOf(
|
||||
*a0.toByteArray(LITTLE_ENDIAN),
|
||||
*b0.toByteArray(LITTLE_ENDIAN),
|
||||
*c0.toByteArray(LITTLE_ENDIAN),
|
||||
*d0.toByteArray(LITTLE_ENDIAN),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user