From c9a003bc53427636ba870f7ad3d1a89620fd8ac4 Mon Sep 17 00:00:00 2001 From: Christian Kollmann Date: Tue, 1 Oct 2024 21:08:14 +0200 Subject: [PATCH 1/3] Reformat shifting bytes Fixes #123 --- .../asn1/encoding/NumberEncoding.kt | 102 ++++++++++++------ 1 file changed, 71 insertions(+), 31 deletions(-) diff --git a/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt b/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt index dcf79eb5..2756caf7 100644 --- a/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt +++ b/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt @@ -125,15 +125,25 @@ fun Long.toTwosComplementByteArray() = when { fun Int.toTwosComplementByteArray() = toLong().toTwosComplementByteArray() fun Int.Companion.fromTwosComplementByteArray(it: ByteArray) = when (it.size) { - 4 -> (it[0].toInt() shl 24) or (it[1].toUByte().toInt() shl 16) or (it[2].toUByte() - .toInt() shl 8) or (it[3].toUByte().toInt()) + 4 -> it.toIntShift(0, 24) or + it.toUByteToIntShift(1, 16) or + it.toUByteToIntShift(2, 8) or + it.toUByteToIntShift(3, 0) - 3 -> (it[0].toInt() shl 16) or (it[1].toUByte().toInt() shl 8) or (it[2].toUByte().toInt()) - 2 -> (it[0].toInt() shl 8) or (it[1].toUByte().toInt() shl 0) - 1 -> (it[0].toInt()) + 3 -> it.toIntShift(0, 16) or + it.toUByteToIntShift(1, 8) or + it.toUByteToIntShift(2, 0) + + 2 -> it.toIntShift(0, 8) or + it.toUByteToIntShift(1, 0) + + 1 -> it.toIntShift(0, 0) else -> throw IllegalArgumentException("Input with size $it is out of bounds for Int") } +private fun ByteArray.toUByteToIntShift(index: Int, shift: Int) = this[index].toUByte().toInt() shl shift +private fun ByteArray.toIntShift(index: Int, shift: Int) = this[index].toInt() shl shift + fun UInt.Companion.fromTwosComplementByteArray(it: ByteArray) = Long.fromTwosComplementByteArray(it).let { require((0 <= it) && (it <= 0xFFFFFFFFL)) { "Value $it is out of bounds for UInt" } @@ -141,36 +151,64 @@ fun UInt.Companion.fromTwosComplementByteArray(it: ByteArray) = } fun Long.Companion.fromTwosComplementByteArray(it: ByteArray) = when (it.size) { - 8 -> (it[0].toLong() shl 56) or (it[1].toUByte().toLong() shl 48) or (it[2].toUByte().toLong() shl 40) or - (it[3].toUByte().toLong() shl 32) or (it[4].toUByte().toLong() shl 24) or - (it[5].toUByte().toLong() shl 16) or (it[6].toUByte().toLong() shl 8) or (it[7].toUByte().toLong()) - - 7 -> (it[0].toLong() shl 48) or (it[1].toUByte().toLong() shl 40) or (it[2].toUByte().toLong() shl 32) or - (it[3].toUByte().toLong() shl 24) or (it[4].toUByte().toLong() shl 16) or - (it[5].toUByte().toLong() shl 8) or (it[6].toUByte().toLong()) - - 6 -> (it[0].toLong() shl 40) or (it[1].toUByte().toLong() shl 32) or (it[2].toUByte().toLong() shl 24) or - (it[3].toUByte().toLong() shl 16) or (it[4].toUByte().toLong() shl 8) or (it[5].toUByte().toLong()) - - 5 -> (it[0].toLong() shl 32) or (it[1].toUByte().toLong() shl 24) or (it[2].toUByte().toLong() shl 16) or - (it[3].toUByte().toLong() shl 8) or (it[4].toUByte().toLong()) - - 4 -> (it[0].toLong() shl 24) or (it[1].toUByte().toLong() shl 16) or (it[2].toUByte().toLong() shl 8) or - (it[3].toUByte().toLong()) - - 3 -> (it[0].toLong() shl 16) or (it[1].toUByte().toLong() shl 8) or (it[2].toUByte().toLong()) - 2 -> (it[0].toLong() shl 8) or (it[1].toUByte().toLong() shl 0) - 1 -> (it[0].toLong()) + 8 -> it.toLongShift(0, 56) or + it.toUByteToLongShift(1, 48) or + it.toUByteToLongShift(2, 40) or + it.toUByteToLongShift(3, 32) or + it.toUByteToLongShift(4, 24) or + it.toUByteToLongShift(5, 16) or + it.toUByteToLongShift(6, 8) or + it.toUByteToLongShift(7, 0) + + 7 -> it.toLongShift(0, 48) or + it.toUByteToLongShift(1, 40) or + it.toUByteToLongShift(2, 32) or + it.toUByteToLongShift(3, 24) or + it.toUByteToLongShift(4, 16) or + it.toUByteToLongShift(5, 8) or + it.toUByteToLongShift(6, 0) + + 6 -> it.toLongShift(0, 40) or + it.toUByteToLongShift(1, 32) or + it.toUByteToLongShift(2, 24) or + it.toUByteToLongShift(3, 16) or + it.toUByteToLongShift(4, 8) or + it.toUByteToLongShift(5, 0) + + 5 -> it.toLongShift(0, 32) or + it.toUByteToLongShift(1, 24) or + it.toUByteToLongShift(2, 16) or + it.toUByteToLongShift(3, 8) or + it.toUByteToLongShift(4, 0) + + 4 -> it.toLongShift(0, 24) or + it.toUByteToLongShift(1, 16) or + it.toUByteToLongShift(2, 8) or + it.toUByteToLongShift(3, 0) + + 3 -> it.toLongShift(0, 16) or + it.toUByteToLongShift(1, 8) or + it.toUByteToLongShift(2, 0) + + 2 -> it.toLongShift(0, 8) or + it.toUByteToLongShift(1, 0) + + 1 -> it.toLongShift(0, 0) else -> throw IllegalArgumentException("Input with size $it is out of bounds for Long") } +private fun ByteArray.toUByteToLongShift(index: Int, shift: Int) = this[index].toUByte().toLong() shl shift +private fun ByteArray.toLongShift(index: Int, shift: Int) = this[index].toLong() shl shift + fun ULong.Companion.fromTwosComplementByteArray(it: ByteArray) = when { - ((it.size == 9) && (it[0] == 0.toByte())) -> - (it[1].toUByte().toULong() shl 56) or (it[2].toUByte().toULong() shl 48) or (it[3].toUByte() - .toULong() shl 40) or - (it[4].toUByte().toULong() shl 32) or (it[5].toUByte().toULong() shl 24) or - (it[6].toUByte().toULong() shl 16) or (it[7].toUByte().toULong() shl 8) or - (it[8].toUByte().toULong()) + ((it.size == 9) && (it[0] == 0.toByte())) -> it.toUByteToULongShift(1, 56) or + it.toUByteToULongShift(2, 48) or + it.toUByteToULongShift(3, 40) or + it.toUByteToULongShift(4, 32) or + it.toUByteToULongShift(5, 24) or + it.toUByteToULongShift(6, 16) or + it.toUByteToULongShift(7, 8) or + it.toUByteToULongShift(8, 0) else -> Long.fromTwosComplementByteArray(it).let { require(it >= 0) { "Value $it is out of bounds for ULong" } @@ -178,6 +216,8 @@ fun ULong.Companion.fromTwosComplementByteArray(it: ByteArray) = when { } } +private fun ByteArray.toUByteToULongShift(index: Int, shift: Int) = this[index].toUByte().toULong() shl shift + /** Encodes an unsigned Long to a minimum-size unsigned byte array */ fun Long.toUnsignedByteArray(): ByteArray { require(this >= 0) From b5d959c05645b63898b793319537a2fab5cc01b0 Mon Sep 17 00:00:00 2001 From: Christian Kollmann Date: Thu, 3 Oct 2024 14:11:50 +0200 Subject: [PATCH 2/3] Rename functions --- .../asn1/encoding/NumberEncoding.kt | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt b/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt index 2756caf7..f303d148 100644 --- a/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt +++ b/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt @@ -125,24 +125,24 @@ fun Long.toTwosComplementByteArray() = when { fun Int.toTwosComplementByteArray() = toLong().toTwosComplementByteArray() fun Int.Companion.fromTwosComplementByteArray(it: ByteArray) = when (it.size) { - 4 -> it.toIntShift(0, 24) or - it.toUByteToIntShift(1, 16) or - it.toUByteToIntShift(2, 8) or - it.toUByteToIntShift(3, 0) + 4 -> it.shiftLeftFirstInt(24) or + it.shiftLeftAsInt(1, 16) or + it.shiftLeftAsInt(2, 8) or + it.shiftLeftAsInt(3, 0) - 3 -> it.toIntShift(0, 16) or - it.toUByteToIntShift(1, 8) or - it.toUByteToIntShift(2, 0) + 3 -> it.shiftLeftFirstInt(16) or + it.shiftLeftAsInt(1, 8) or + it.shiftLeftAsInt(2, 0) - 2 -> it.toIntShift(0, 8) or - it.toUByteToIntShift(1, 0) + 2 -> it.shiftLeftFirstInt(8) or + it.shiftLeftAsInt(1, 0) - 1 -> it.toIntShift(0, 0) + 1 -> it.shiftLeftFirstInt(0) else -> throw IllegalArgumentException("Input with size $it is out of bounds for Int") } -private fun ByteArray.toUByteToIntShift(index: Int, shift: Int) = this[index].toUByte().toInt() shl shift -private fun ByteArray.toIntShift(index: Int, shift: Int) = this[index].toInt() shl shift +private fun ByteArray.shiftLeftAsInt(index: Int, shift: Int) = this[index].toUByte().toInt() shl shift +private fun ByteArray.shiftLeftFirstInt(shift: Int) = this[0].toInt() shl shift fun UInt.Companion.fromTwosComplementByteArray(it: ByteArray) = Long.fromTwosComplementByteArray(it).let { @@ -151,64 +151,64 @@ fun UInt.Companion.fromTwosComplementByteArray(it: ByteArray) = } fun Long.Companion.fromTwosComplementByteArray(it: ByteArray) = when (it.size) { - 8 -> it.toLongShift(0, 56) or - it.toUByteToLongShift(1, 48) or - it.toUByteToLongShift(2, 40) or - it.toUByteToLongShift(3, 32) or - it.toUByteToLongShift(4, 24) or - it.toUByteToLongShift(5, 16) or - it.toUByteToLongShift(6, 8) or - it.toUByteToLongShift(7, 0) - - 7 -> it.toLongShift(0, 48) or - it.toUByteToLongShift(1, 40) or - it.toUByteToLongShift(2, 32) or - it.toUByteToLongShift(3, 24) or - it.toUByteToLongShift(4, 16) or - it.toUByteToLongShift(5, 8) or - it.toUByteToLongShift(6, 0) - - 6 -> it.toLongShift(0, 40) or - it.toUByteToLongShift(1, 32) or - it.toUByteToLongShift(2, 24) or - it.toUByteToLongShift(3, 16) or - it.toUByteToLongShift(4, 8) or - it.toUByteToLongShift(5, 0) - - 5 -> it.toLongShift(0, 32) or - it.toUByteToLongShift(1, 24) or - it.toUByteToLongShift(2, 16) or - it.toUByteToLongShift(3, 8) or - it.toUByteToLongShift(4, 0) - - 4 -> it.toLongShift(0, 24) or - it.toUByteToLongShift(1, 16) or - it.toUByteToLongShift(2, 8) or - it.toUByteToLongShift(3, 0) - - 3 -> it.toLongShift(0, 16) or - it.toUByteToLongShift(1, 8) or - it.toUByteToLongShift(2, 0) - - 2 -> it.toLongShift(0, 8) or - it.toUByteToLongShift(1, 0) - - 1 -> it.toLongShift(0, 0) + 8 -> it.shiftLeftFirstLong(56) or + it.shiftLeftAsLong(1, 48) or + it.shiftLeftAsLong(2, 40) or + it.shiftLeftAsLong(3, 32) or + it.shiftLeftAsLong(4, 24) or + it.shiftLeftAsLong(5, 16) or + it.shiftLeftAsLong(6, 8) or + it.shiftLeftAsLong(7, 0) + + 7 -> it.shiftLeftFirstLong(48) or + it.shiftLeftAsLong(1, 40) or + it.shiftLeftAsLong(2, 32) or + it.shiftLeftAsLong(3, 24) or + it.shiftLeftAsLong(4, 16) or + it.shiftLeftAsLong(5, 8) or + it.shiftLeftAsLong(6, 0) + + 6 -> it.shiftLeftFirstLong(40) or + it.shiftLeftAsLong(1, 32) or + it.shiftLeftAsLong(2, 24) or + it.shiftLeftAsLong(3, 16) or + it.shiftLeftAsLong(4, 8) or + it.shiftLeftAsLong(5, 0) + + 5 -> it.shiftLeftFirstLong(32) or + it.shiftLeftAsLong(1, 24) or + it.shiftLeftAsLong(2, 16) or + it.shiftLeftAsLong(3, 8) or + it.shiftLeftAsLong(4, 0) + + 4 -> it.shiftLeftFirstLong(24) or + it.shiftLeftAsLong(1, 16) or + it.shiftLeftAsLong(2, 8) or + it.shiftLeftAsLong(3, 0) + + 3 -> it.shiftLeftFirstLong(16) or + it.shiftLeftAsLong(1, 8) or + it.shiftLeftAsLong(2, 0) + + 2 -> it.shiftLeftFirstLong(8) or + it.shiftLeftAsLong(1, 0) + + 1 -> it.shiftLeftFirstLong(0) else -> throw IllegalArgumentException("Input with size $it is out of bounds for Long") } -private fun ByteArray.toUByteToLongShift(index: Int, shift: Int) = this[index].toUByte().toLong() shl shift -private fun ByteArray.toLongShift(index: Int, shift: Int) = this[index].toLong() shl shift +private fun ByteArray.shiftLeftAsLong(index: Int, shift: Int) = this[index].toUByte().toLong() shl shift +private fun ByteArray.shiftLeftFirstLong(shift: Int) = this[0].toLong() shl shift fun ULong.Companion.fromTwosComplementByteArray(it: ByteArray) = when { - ((it.size == 9) && (it[0] == 0.toByte())) -> it.toUByteToULongShift(1, 56) or - it.toUByteToULongShift(2, 48) or - it.toUByteToULongShift(3, 40) or - it.toUByteToULongShift(4, 32) or - it.toUByteToULongShift(5, 24) or - it.toUByteToULongShift(6, 16) or - it.toUByteToULongShift(7, 8) or - it.toUByteToULongShift(8, 0) + ((it.size == 9) && (it[0] == 0.toByte())) -> it.shiftLeftAsULong(1, 56) or + it.shiftLeftAsULong(2, 48) or + it.shiftLeftAsULong(3, 40) or + it.shiftLeftAsULong(4, 32) or + it.shiftLeftAsULong(5, 24) or + it.shiftLeftAsULong(6, 16) or + it.shiftLeftAsULong(7, 8) or + it.shiftLeftAsULong(8, 0) else -> Long.fromTwosComplementByteArray(it).let { require(it >= 0) { "Value $it is out of bounds for ULong" } @@ -216,7 +216,7 @@ fun ULong.Companion.fromTwosComplementByteArray(it: ByteArray) = when { } } -private fun ByteArray.toUByteToULongShift(index: Int, shift: Int) = this[index].toUByte().toULong() shl shift +private fun ByteArray.shiftLeftAsULong(index: Int, shift: Int) = this[index].toUByte().toULong() shl shift /** Encodes an unsigned Long to a minimum-size unsigned byte array */ fun Long.toUnsignedByteArray(): ByteArray { From 2b87948108830218029bdc3349a10d12f32d438b Mon Sep 17 00:00:00 2001 From: Christian Kollmann Date: Thu, 3 Oct 2024 14:16:25 +0200 Subject: [PATCH 3/3] Convert to infix functions --- .../asn1/encoding/NumberEncoding.kt | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt b/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt index f303d148..e0565b2c 100644 --- a/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt +++ b/indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/asn1/encoding/NumberEncoding.kt @@ -125,24 +125,24 @@ fun Long.toTwosComplementByteArray() = when { fun Int.toTwosComplementByteArray() = toLong().toTwosComplementByteArray() fun Int.Companion.fromTwosComplementByteArray(it: ByteArray) = when (it.size) { - 4 -> it.shiftLeftFirstInt(24) or - it.shiftLeftAsInt(1, 16) or - it.shiftLeftAsInt(2, 8) or - it.shiftLeftAsInt(3, 0) + 4 -> it[0].shiftLeftFirstInt(24) or + (it[1] shiftLeftAsInt 16) or + (it[2] shiftLeftAsInt 8) or + (it[3] shiftLeftAsInt 0) - 3 -> it.shiftLeftFirstInt(16) or - it.shiftLeftAsInt(1, 8) or - it.shiftLeftAsInt(2, 0) + 3 -> it[0].shiftLeftFirstInt(16) or + (it[1] shiftLeftAsInt 8) or + (it[2] shiftLeftAsInt 0) - 2 -> it.shiftLeftFirstInt(8) or - it.shiftLeftAsInt(1, 0) + 2 -> it[0].shiftLeftFirstInt(8) or + (it[1] shiftLeftAsInt 0) - 1 -> it.shiftLeftFirstInt(0) + 1 -> it[0].shiftLeftFirstInt(0) else -> throw IllegalArgumentException("Input with size $it is out of bounds for Int") } -private fun ByteArray.shiftLeftAsInt(index: Int, shift: Int) = this[index].toUByte().toInt() shl shift -private fun ByteArray.shiftLeftFirstInt(shift: Int) = this[0].toInt() shl shift +private infix fun Byte.shiftLeftAsInt(shift: Int) = this.toUByte().toInt() shl shift +private fun Byte.shiftLeftFirstInt(shift: Int) = toInt() shl shift fun UInt.Companion.fromTwosComplementByteArray(it: ByteArray) = Long.fromTwosComplementByteArray(it).let { @@ -151,54 +151,54 @@ fun UInt.Companion.fromTwosComplementByteArray(it: ByteArray) = } fun Long.Companion.fromTwosComplementByteArray(it: ByteArray) = when (it.size) { - 8 -> it.shiftLeftFirstLong(56) or - it.shiftLeftAsLong(1, 48) or - it.shiftLeftAsLong(2, 40) or - it.shiftLeftAsLong(3, 32) or - it.shiftLeftAsLong(4, 24) or - it.shiftLeftAsLong(5, 16) or - it.shiftLeftAsLong(6, 8) or - it.shiftLeftAsLong(7, 0) - - 7 -> it.shiftLeftFirstLong(48) or - it.shiftLeftAsLong(1, 40) or - it.shiftLeftAsLong(2, 32) or - it.shiftLeftAsLong(3, 24) or - it.shiftLeftAsLong(4, 16) or - it.shiftLeftAsLong(5, 8) or - it.shiftLeftAsLong(6, 0) - - 6 -> it.shiftLeftFirstLong(40) or - it.shiftLeftAsLong(1, 32) or - it.shiftLeftAsLong(2, 24) or - it.shiftLeftAsLong(3, 16) or - it.shiftLeftAsLong(4, 8) or - it.shiftLeftAsLong(5, 0) - - 5 -> it.shiftLeftFirstLong(32) or - it.shiftLeftAsLong(1, 24) or - it.shiftLeftAsLong(2, 16) or - it.shiftLeftAsLong(3, 8) or - it.shiftLeftAsLong(4, 0) - - 4 -> it.shiftLeftFirstLong(24) or - it.shiftLeftAsLong(1, 16) or - it.shiftLeftAsLong(2, 8) or - it.shiftLeftAsLong(3, 0) - - 3 -> it.shiftLeftFirstLong(16) or - it.shiftLeftAsLong(1, 8) or - it.shiftLeftAsLong(2, 0) - - 2 -> it.shiftLeftFirstLong(8) or - it.shiftLeftAsLong(1, 0) - - 1 -> it.shiftLeftFirstLong(0) + 8 -> it[0].shiftLeftFirstLong(56) or + (it[1] shiftLeftAsLong 48) or + (it[2] shiftLeftAsLong 40) or + (it[3] shiftLeftAsLong 32) or + (it[4] shiftLeftAsLong 24) or + (it[5] shiftLeftAsLong 16) or + (it[6] shiftLeftAsLong 8) or + (it[7] shiftLeftAsLong 0) + + 7 -> it[0].shiftLeftFirstLong(48) or + (it[1] shiftLeftAsLong 40) or + (it[2] shiftLeftAsLong 32) or + (it[3] shiftLeftAsLong 24) or + (it[4] shiftLeftAsLong 16) or + (it[5] shiftLeftAsLong 8) or + (it[6] shiftLeftAsLong 0) + + 6 -> it[0].shiftLeftFirstLong(40) or + (it[1] shiftLeftAsLong 32) or + (it[2] shiftLeftAsLong 24) or + (it[3] shiftLeftAsLong 16) or + (it[4] shiftLeftAsLong 8) or + (it[5] shiftLeftAsLong 0) + + 5 -> it[0].shiftLeftFirstLong(32) or + (it[1] shiftLeftAsLong 24) or + (it[2] shiftLeftAsLong 16) or + (it[3] shiftLeftAsLong 8) or + (it[4] shiftLeftAsLong 0) + + 4 -> it[0].shiftLeftFirstLong(24) or + (it[1] shiftLeftAsLong 16) or + (it[2] shiftLeftAsLong 8) or + (it[3] shiftLeftAsLong 0) + + 3 -> it[0].shiftLeftFirstLong(16) or + (it[1] shiftLeftAsLong 8) or + (it[2] shiftLeftAsLong 0) + + 2 -> it[0].shiftLeftFirstLong(8) or + (it[1] shiftLeftAsLong 0) + + 1 -> it[0].shiftLeftFirstLong(0) else -> throw IllegalArgumentException("Input with size $it is out of bounds for Long") } -private fun ByteArray.shiftLeftAsLong(index: Int, shift: Int) = this[index].toUByte().toLong() shl shift -private fun ByteArray.shiftLeftFirstLong(shift: Int) = this[0].toLong() shl shift +private infix fun Byte.shiftLeftAsLong(shift: Int) = this.toUByte().toLong() shl shift +private fun Byte.shiftLeftFirstLong(shift: Int) = toLong() shl shift fun ULong.Companion.fromTwosComplementByteArray(it: ByteArray) = when { ((it.size == 9) && (it[0] == 0.toByte())) -> it.shiftLeftAsULong(1, 56) or