refactor hash functions
This commit is contained in:
@@ -12,26 +12,23 @@ object MD5 : HashFunction() {
|
||||
override val block: Int
|
||||
get() = 64
|
||||
|
||||
private val s = intArrayOf(
|
||||
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 initial = uintArrayOf(
|
||||
0x67452301U, 0xefcdab89U,
|
||||
0x98badcfeU, 0x10325476U,
|
||||
)
|
||||
|
||||
private val k = uintArrayOf(
|
||||
private val shifts = intArrayOf(
|
||||
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 c = uintArrayOf(
|
||||
0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU,
|
||||
0xf57c0fafU, 0x4787c62aU, 0xa8304613U, 0xfd469501U,
|
||||
0x698098d8U, 0x8b44f7afU, 0xffff5bb1U, 0x895cd7beU,
|
||||
@@ -53,64 +50,58 @@ object MD5 : HashFunction() {
|
||||
override fun hash(
|
||||
value: UByteArray,
|
||||
): UByteArray {
|
||||
var a0 = 0x67452301U
|
||||
var b0 = 0xefcdab89U
|
||||
var c0 = 0x98badcfeU
|
||||
var d0 = 0x10325476U
|
||||
val ml = value.size.toULong() * 8UL
|
||||
val h = initial.copyOf()
|
||||
val l = value.size.toULong() * 8UL
|
||||
|
||||
// padding
|
||||
val paddedValue = buildList {
|
||||
addAll(value)
|
||||
add(0x80U)
|
||||
while (size % 64 != 56) {
|
||||
add(0x00U)
|
||||
}
|
||||
addAll(ml.toUByteArray(LITTLE_ENDIAN))
|
||||
addAll(l.toUByteArray(LITTLE_ENDIAN))
|
||||
}
|
||||
|
||||
val chunks = paddedValue
|
||||
// process
|
||||
val blocks = paddedValue
|
||||
.chunked(64) { it.toUByteArray() }
|
||||
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
|
||||
}
|
||||
val temp = a
|
||||
a = d
|
||||
d = c
|
||||
c = b
|
||||
b += (temp + f + k[i] + w[g]).rotateLeft(s[i])
|
||||
}
|
||||
|
||||
a0 += a
|
||||
b0 += b
|
||||
c0 += c
|
||||
d0 += d
|
||||
for (block in blocks) {
|
||||
val w = block.toUIntArray(LITTLE_ENDIAN)
|
||||
process(h, w)
|
||||
}
|
||||
|
||||
return ubyteArrayOf(
|
||||
*a0.toUByteArray(LITTLE_ENDIAN),
|
||||
*b0.toUByteArray(LITTLE_ENDIAN),
|
||||
*c0.toUByteArray(LITTLE_ENDIAN),
|
||||
*d0.toUByteArray(LITTLE_ENDIAN),
|
||||
)
|
||||
return h.toUByteArray(LITTLE_ENDIAN)
|
||||
}
|
||||
|
||||
private fun process(
|
||||
h: UIntArray,
|
||||
w: UIntArray,
|
||||
) {
|
||||
val v = h.copyOf()
|
||||
|
||||
for (i in 0..<64) {
|
||||
var f = when (i) {
|
||||
in 0..15 -> (v[1] and v[2]) or (v[1].inv() and v[3])
|
||||
in 16..31 -> (v[3] and v[1]) or (v[3].inv() and v[2])
|
||||
in 32..47 -> v[1] xor v[2] xor v[3]
|
||||
else -> v[2] xor (v[1] or v[3].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
|
||||
}
|
||||
f += v[0] + c[i] + w[g]
|
||||
v[0] = v[3]
|
||||
v[3] = v[2]
|
||||
v[2] = v[1]
|
||||
v[1] += f.rotateLeft(shifts[i])
|
||||
}
|
||||
|
||||
for (i in 0..3) {
|
||||
h[i] += v[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user