commonMain.CommonUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kmqtt-common-jvm Show documentation
Show all versions of kmqtt-common-jvm Show documentation
Kotlin Multiplatform MQTT client & embeddable and standalone broker
import socket.streams.ByteArrayOutputStream
import kotlin.random.Random
public expect fun currentTimeMillis(): Long
public fun generateRandomClientId(): String {
val length = 30
val buffer = StringBuilder(length)
for (i in 0 until length) {
buffer.append(Random.Default.nextInt(97, 122).toChar())
}
return buffer.toString()
}
public fun UByteArray.validatePayloadFormat(indicator: UInt): Boolean {
if (indicator == 1u) {
return this.toByteArray().decodeToString().validateUTF8String()
}
return true
}
public fun String.validateUTF8String(): Boolean {
this.forEachIndexed { index, character ->
if (character == '\u0000')
return false
if (character == '\uFFFD')
return false
if (character in '\uD800'..'\uDFFF') {
this.getOrNull(index + 1)?.let {
if (it !in '\uDC00'..'\uDFFF')
return false
} ?: return false
}
}
return true
}
public fun UByteArray.toHexString(): String = joinToString("") { it.toString(16).padStart(2, '0') }
public fun UIntArray.toHexString(): String = joinToString("") { it.toString(16).padStart(8, '0') }
public fun String.fromHexString(): ByteArray = chunked(2).map { it.toInt(16).toByte() }.toByteArray()
public fun MutableMap.removeIf(predicate: (MutableMap.MutableEntry) -> Boolean): Boolean {
var removed = false
val iterator = iterator()
while (iterator.hasNext()) {
val next = iterator.next()
if (predicate(next)) {
iterator.remove()
removed = true
}
}
return removed
}
private infix fun UInt.leftRotate(bits: Int): UInt = ((this shl bits) or (this shr (32 - bits)))
public fun ByteArray.sha1(): ByteArray {
val hash = UIntArray(5)
hash[0] = 0x67452301u
hash[1] = 0xEFCDAB89u
hash[2] = 0x98BADCFEu
hash[3] = 0x10325476u
hash[4] = 0xC3D2E1F0u
val ml = (this.size * 8).toULong()
// Prepare the data
val outStream = ByteArrayOutputStream()
outStream.write(this.toUByteArray())
outStream.write(0x80u)
while ((outStream.size() + 8) % 64 != 0) {
outStream.write(0u)
}
outStream.writeULong(ml)
val data = outStream.toByteArray()
for (j in data.indices step 64) {
val w = UIntArray(80)
for (i in 0 until 16) {
w[i] = (data[j + i * 4].toUInt() shl 24) or
(data[j + i * 4 + 1].toUInt() shl 16) or
(data[j + i * 4 + 2].toUInt() shl 8) or
data[j + i * 4 + 3].toUInt()
}
for (i in 16 until 80) {
w[i] = (w[i - 3] xor w[i - 8] xor w[i - 14] xor w[i - 16]) leftRotate 1
}
var a = hash[0]
var b = hash[1]
var c = hash[2]
var d = hash[3]
var e = hash[4]
var f = 0u
var k = 0u
for (i in 0 until 80) {
when (i) {
in 0..19 -> {
f = (b and c) or (b.inv() and d)
k = 0x5A827999u
}
in 20..39 -> {
f = b xor c xor d
k = 0x6ED9EBA1u
}
in 40..59 -> {
f = (b and c) or (b and d) or (c and d)
k = 0x8F1BBCDCu
}
in 60..79 -> {
f = b xor c xor d
k = 0xCA62C1D6u
}
}
val temp = (a leftRotate 5) + f + e + k + w[i]
e = d
d = c
c = b leftRotate 30
b = a
a = temp
}
hash[0] += a
hash[1] += b
hash[2] += c
hash[3] += d
hash[4] += e
}
val hexString = hash.toHexString()
return hexString.fromHexString()
}
public fun ByteArray.toBase64(): String {
val base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
var r = ""
var p = ""
var c = this.size % 3
val outStream = ByteArrayOutputStream()
outStream.write(this.toUByteArray())
if (c > 0) {
while (c < 3) {
p += "="
outStream.write(0u)
c++
}
}
val s = outStream.toByteArray()
c = 0
while (c < this.size) {
if (c > 0 && (c / 3 * 4) % 76 == 0) {
r += "\r\n"
}
val n = (s[c].toInt() shl 16) + (s[c + 1].toInt() shl 8) + s[c + 2].toInt()
val n1 = n shr 18 and 63
val n2 = n shr 12 and 63
val n3 = n shr 6 and 63
val n4 = n and 63
r += ("" + base64chars[n1] + base64chars[n2] + base64chars[n3] + base64chars[n4])
c += 3
}
return r.substring(0, r.length - p.length) + p
}
public fun String.isValidPem(): Boolean {
return matches("(-----BEGIN PUBLIC KEY-----(\\n|\\r|\\r\\n)([0-9a-zA-Z+/=]{64}(\\n|\\r|\\r\\n))*([0-9a-zA-Z+/=]{1,63}(\\n|\\r|\\r\\n))?-----END PUBLIC KEY-----(\\n|\\r|\\r\\n)?)|(-----BEGIN PRIVATE KEY-----(\\n|\\r|\\r\\n)([0-9a-zA-Z+/=]{64}(\\n|\\r|\\r\\n))*([0-9a-zA-Z+/=]{1,63}(\\n|\\r|\\r\\n))?-----END PRIVATE KEY-----(\\n|\\r|\\r\\n)?)|(-----BEGIN CERTIFICATE-----(\\n|\\r|\\r\\n)([0-9a-zA-Z+/=]{64}(\\n|\\r|\\r\\n))*([0-9a-zA-Z+/=]{1,63}(\\n|\\r|\\r\\n))?-----END CERTIFICATE-----(\\n|\\r|\\r\\n)?)".toRegex())
}