1.3.0 release #7

Merged
Infendro merged 13 commits from develop into main 2026-01-29 16:46:03 +00:00
22 changed files with 355 additions and 249 deletions
Showing only changes of commit 55faf1d670 - Show all commits

View File

@@ -1,16 +0,0 @@
package com.infendro.encoding
object Base16 : Encoding() {
private val CHARACTERS = ubyteArrayOf(
0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U,
0x38U, 0x39U, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U,
)
override fun encode(
bytes: UByteArray,
) = encode(bytes, CHARACTERS)
override fun decode(
bytes: UByteArray,
) = decode(bytes, CHARACTERS)
}

View File

@@ -1,15 +0,0 @@
package com.infendro.encoding
object Base2 : Encoding() {
private val CHARACTERS = ubyteArrayOf(
0x30U, 0x31U,
)
override fun encode(
bytes: UByteArray,
) = encode(bytes, CHARACTERS)
override fun decode(
bytes: UByteArray,
) = decode(bytes, CHARACTERS)
}

View File

@@ -1,19 +0,0 @@
package com.infendro.encoding
object Base32 : Encoding() {
private val CHARACTERS = ubyteArrayOf(
0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U,
0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U,
0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U,
0x59U, 0x5aU, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U,
)
private const val PADDING: UByte = 0x3dU
override fun encode(
bytes: UByteArray,
) = encode(bytes, CHARACTERS, PADDING)
override fun decode(
bytes: UByteArray,
) = decode(bytes, CHARACTERS, PADDING)
}

View File

@@ -1,23 +0,0 @@
package com.infendro.encoding
object Base64 : Encoding() {
private val CHARACTERS = ubyteArrayOf(
0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U,
0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U,
0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U,
0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U,
0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU,
0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U,
0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U,
0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU,
)
private const val PADDING: UByte = 0x3dU
override fun encode(
bytes: UByteArray,
) = encode(bytes, CHARACTERS, PADDING)
override fun decode(
bytes: UByteArray,
) = decode(bytes, CHARACTERS, PADDING)
}

View File

@@ -1,15 +0,0 @@
package com.infendro.encoding
object Base8 : Encoding() {
private val CHARACTERS = ubyteArrayOf(
0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U,
)
override fun encode(
bytes: UByteArray,
) = encode(bytes, CHARACTERS)
override fun decode(
bytes: UByteArray,
) = decode(bytes, CHARACTERS)
}

View File

@@ -1,92 +1,15 @@
package com.infendro.encoding package com.infendro.encoding
import com.infendro.encoding.util.lcm abstract class Encoding(
import com.infendro.encoding.util.log2 val alphabet: ByteArray,
import kotlin.math.pow ) {
init {
sealed class Encoding { require(alphabet.isNotEmpty())
abstract fun encode(
bytes: UByteArray,
): UByteArray
abstract fun decode(
bytes: UByteArray,
): UByteArray
protected fun encode(
bytes: UByteArray,
characters: UByteArray,
padding: UByte? = null,
): UByteArray {
val length = log2(characters.size).toInt()
val mask = (2.0.pow(length) - 1).toUInt()
val encoded = mutableListOf<UByte>()
var buffer = 0U
var bits = 0
for (byte in bytes) {
buffer = (buffer shl 8) + byte
bits += 8
while (bits >= length) {
val offset = bits - length
val index = (buffer shr offset).toInt()
buffer = buffer and (mask shl offset).inv()
bits -= length
encoded.add(characters[index])
}
}
if (bits > 0) {
buffer = buffer shl (length - bits)
val index = buffer.toInt()
encoded.add(characters[index])
}
if (padding != null) {
val block = lcm(length, 8) / length
while (encoded.size % block != 0) {
encoded.add(padding)
}
}
return encoded.toUByteArray()
} }
protected fun decode( val base: Int
bytes: UByteArray, get() = alphabet.size
characters: UByteArray,
padding: UByte? = null,
): UByteArray {
val length = log2(characters.size).toInt()
val mask = 0xffU
val decoded = mutableListOf<UByte>() abstract fun encode(bytes: ByteArray): ByteArray
abstract fun decode(bytes: ByteArray): ByteArray
var buffer = 0U
var bits = 0
for (byte in bytes) {
if (byte == padding) break
val index = characters.indexOf(byte)
if (index == -1) throw Exception()
buffer = (buffer shl length) + index.toUByte()
bits += length
if (bits >= 8) {
val offset = bits - 8
val character = (buffer shr offset).toUByte()
buffer = buffer and (mask shl offset).inv()
bits -= 8
decoded.add(character)
}
}
return decoded.toUByteArray()
}
} }

View File

@@ -0,0 +1,5 @@
package com.infendro.encoding.numeric
private val alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".encodeToByteArray()
object Base36 : NumericEncoding(alphabet)

View File

@@ -0,0 +1,5 @@
package com.infendro.encoding.numeric
private val alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".encodeToByteArray()
object Base62 : NumericEncoding(alphabet)

View File

@@ -0,0 +1,40 @@
package com.infendro.encoding.numeric
import com.infendro.encoding.Encoding
import com.infendro.encoding.util.BigInt
import com.infendro.encoding.util.log2
import kotlin.math.ceil
open class NumericEncoding(
alphabet: ByteArray,
) : Encoding(alphabet) {
override fun encode(bytes: ByteArray): ByteArray {
if (bytes.isEmpty()) return byteArrayOf()
val size = ceil(bytes.size * 8 / log2(base)).toInt()
val result = ByteArray(size)
var x = BigInt.from(bytes)
var i = result.size
while (!x.isZero()) {
val (quotient, remainder) = x.divRem(base)
x = quotient
result[--i] = alphabet[remainder]
}
return result.copyOfRange(i, result.size)
}
override fun decode(bytes: ByteArray): ByteArray {
if (bytes.isEmpty()) return byteArrayOf()
var value = BigInt.zero
for (i in 0..<bytes.size) {
val index = alphabet.indexOf(bytes[i])
if (index == -1) throw Exception() //TODO
value = value.timesAdd(base, index)
}
return value.toByteArray()
}
}

View File

@@ -0,0 +1,5 @@
package com.infendro.encoding.stream
private val alphabet = "0123456789ABCDEF".encodeToByteArray()
object Base16 : StreamEncoding(alphabet)

View File

@@ -0,0 +1,5 @@
package com.infendro.encoding.stream
private val alphabet = "01".encodeToByteArray()
object Base2 : StreamEncoding(alphabet)

View File

@@ -0,0 +1,6 @@
package com.infendro.encoding.stream
private val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".encodeToByteArray()
private const val padding = '='.code.toByte()
object Base32 : StreamEncoding(alphabet, padding)

View File

@@ -0,0 +1,6 @@
package com.infendro.encoding.stream
private val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".encodeToByteArray()
private const val padding = '='.code.toByte()
object Base64 : StreamEncoding(alphabet, padding)

View File

@@ -0,0 +1,5 @@
package com.infendro.encoding.stream
private val alphabet = "01234567".encodeToByteArray()
object Base8 : StreamEncoding(alphabet)

View File

@@ -0,0 +1,96 @@
package com.infendro.encoding.stream
import com.infendro.encoding.Encoding
import com.infendro.encoding.util.align
import com.infendro.encoding.util.divCeil
import com.infendro.encoding.util.lcm
import com.infendro.encoding.util.log2
open class StreamEncoding(
alphabet: ByteArray,
private val padding: Byte? = null,
) : Encoding(alphabet) {
init {
require(base % 2 == 0)
}
override fun encode(bytes: ByteArray): ByteArray {
val bits = log2(base).toInt()
val size = (bytes.size * 8).divCeil(bits)
val encodedSize = when (padding) {
null -> size
else -> {
val block = lcm(bits, 8) / bits
size.align(block)
}
}
val result = ByteArray(encodedSize)
var r = 0
var buffer = 0
var bufferBits = 0
for (i in bytes.indices) {
buffer = (buffer shl 8) + bytes[i]
bufferBits += 8
while (bufferBits >= bits) {
val offset = bufferBits - bits
val index = (buffer ushr offset)
buffer = buffer and ((base - 1) shl offset).inv()
bufferBits -= bits
result[r++] = alphabet[index]
}
}
if (bufferBits > 0) {
buffer = buffer shl (bits - bufferBits)
val index = buffer
result[r++] = alphabet[index]
}
if (padding != null) {
while (r < result.size) {
result[r++] = padding
}
}
return result
}
override fun decode(bytes: ByteArray): ByteArray {
val bits = log2(base).toInt()
val index = padding?.let { bytes.indexOf(it) } ?: -1
val decodedSize = when (index) {
-1 -> bytes.size * bits / 8
else -> index * bits / 8
}
val result = ByteArray(decodedSize)
var r = 0
var buffer = 0
var bufferBits = 0
for (i in bytes.indices) {
val byte = bytes[i]
if (byte == padding) break
val index = alphabet.indexOf(byte)
if (index == -1) throw Exception() //TODO
buffer = (buffer shl bits) + index.toByte()
bufferBits += bits
if (bufferBits >= 8) {
val offset = bufferBits - 8
val character = (buffer ushr offset).toByte()
buffer = buffer and (0xFF shl offset).inv()
bufferBits -= 8
result[r++] = character
}
}
return result
}
}

View File

@@ -0,0 +1,89 @@
package com.infendro.encoding.util
internal class BigInt private constructor(
val words: IntArray,
) {
init {
require(words.isNotEmpty())
}
fun isZero(): Boolean = words.all { it == 0 }
fun timesAdd(multiplier: Int, addend: Int): BigInt {
val product = IntArray(words.size)
var carry = addend
for (i in words.indices) {
val current = (words[i].toLong() and 0xFFFFFFFFL) * multiplier + carry
product[i] = current.toInt()
carry = (current ushr 32).toInt()
}
when {
carry > 0 -> {
val expanded = product.copyOf(product.size + 1)
expanded[product.size] = carry
return BigInt(expanded)
}
else -> return BigInt(product)
}
}
fun divRem(divisor: Int): Pair<BigInt, Int> {
val quotient = IntArray(words.size)
var remainder = 0
for (i in words.indices.reversed()) {
val current = (remainder.toLong() shl 32) or (words[i].toLong() and 0xFFFFFFFFL)
quotient[i] = (current / divisor.toLong()).toInt()
remainder = (current % divisor.toLong()).toInt()
}
when {
quotient.size > 1 && quotient.last() == 0 -> {
val contracted = quotient.copyOfRange(0, quotient.size - 1)
return Pair(BigInt(contracted), remainder)
}
else -> return Pair(BigInt(quotient), remainder)
}
}
fun toByteArray(): ByteArray {
val msw = words.last()
val mswBytes = when {
(msw ushr 24) != 0 -> 4
(msw ushr 16) != 0 -> 3
(msw ushr 8) != 0 -> 2
else -> 1
}
val size = ((words.size - 1) * 4) + mswBytes
val result = ByteArray(size)
for (i in 0..<size) {
val index = size - 1 - i
val shift = (index % 4) * 8
result[i] = (words[index / 4] ushr shift).toByte()
}
return result
}
companion object {
val zero: BigInt
get() = BigInt(intArrayOf(0))
fun from(value: ByteArray): BigInt {
val size = value.size.divCeil(4)
val words = IntArray(size)
for (i in value.indices) {
val byte = value[i].toInt() and 0xFF
val index = value.lastIndex - i
val shift = (index % 4) * 8
words[index / 4] = words[index / 4] or (byte shl shift)
}
return BigInt(words)
}
}
}

View File

@@ -2,14 +2,16 @@ package com.infendro.encoding.util
import kotlin.math.log2 import kotlin.math.log2
internal fun log2( internal fun log2(value: Int): Double =
value: Int, log2(value.toDouble())
) = log2(value.toDouble())
internal fun gcd( internal fun Int.divCeil(n: Int): Int =
a: Int, (this + n - 1) / n
b: Int,
): Int { internal fun Int.align(n: Int): Int =
divCeil(n) * n
internal fun gcd(a: Int, b: Int): Int {
var x = a var x = a
var y = b var y = b
while (y != 0) { while (y != 0) {
@@ -20,9 +22,6 @@ internal fun gcd(
return x return x
} }
internal fun lcm( internal fun lcm(a: Int, b: Int): Int {
a: Int,
b: Int,
): Int {
return (a * b) / gcd(a, b) return (a * b) / gcd(a, b)
} }

View File

@@ -1,31 +1,33 @@
package com.infendro.encoding package com.infendro.encoding
import com.infendro.encoding.stream.Base16
import com.infendro.encoding.stream.StreamEncoding
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
class `Base16 Test` { class `Base16 Test` {
val encoding: Encoding val encoding: StreamEncoding
get() = Base16 get() = Base16
val `Hello World!` = ubyteArrayOf( val `Hello World!` = byteArrayOf(
0x48U, 0x65U, 0x6cU, 0x6cU, 0x48, 0x65, 0x6c, 0x6c,
0x6fU, 0x20U, 0x57U, 0x6fU, 0x6f, 0x20, 0x57, 0x6f,
0x72U, 0x6cU, 0x64U, 0x21U, 0x72, 0x6c, 0x64, 0x21,
) )
@Test @Test
fun `encode empty ByteArray`() { fun `encode empty ByteArray`() {
val expected = ubyteArrayOf() val expected = byteArrayOf()
val actual = encoding.encode(ubyteArrayOf()) val actual = encoding.encode(byteArrayOf())
assertContentEquals(expected, actual) assertContentEquals(expected, actual)
} }
@Test @Test
fun `encode "Hello World!"`() { fun `encode "Hello World!"`() {
val expected = ubyteArrayOf( val expected = byteArrayOf(
0x34U, 0x38U, 0x36U, 0x35U, 0x36U, 0x63U, 0x36U, 0x63U, 0x34, 0x38, 0x36, 0x35, 0x36, 0x63, 0x36, 0x63,
0x36U, 0x66U, 0x32U, 0x30U, 0x35U, 0x37U, 0x36U, 0x66U, 0x36, 0x66, 0x32, 0x30, 0x35, 0x37, 0x36, 0x66,
0x37U, 0x32U, 0x36U, 0x63U, 0x36U, 0x34U, 0x32U, 0x31U, 0x37, 0x32, 0x36, 0x63, 0x36, 0x34, 0x32, 0x31,
) )
val actual = encoding.encode(`Hello World!`) val actual = encoding.encode(`Hello World!`)
assertContentEquals(expected, actual) assertContentEquals(expected, actual)

View File

@@ -1,40 +1,42 @@
package com.infendro.encoding package com.infendro.encoding
import com.infendro.encoding.stream.Base2
import com.infendro.encoding.stream.StreamEncoding
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
class `Base2 Test` { class `Base2 Test` {
val encoding: Encoding val encoding: StreamEncoding
get() = Base2 get() = Base2
val `Hello World!` = ubyteArrayOf( val `Hello World!` = byteArrayOf(
0x48U, 0x65U, 0x6cU, 0x6cU, 0x48, 0x65, 0x6c, 0x6c,
0x6fU, 0x20U, 0x57U, 0x6fU, 0x6f, 0x20, 0x57, 0x6f,
0x72U, 0x6cU, 0x64U, 0x21U, 0x72, 0x6c, 0x64, 0x21,
) )
@Test @Test
fun `encode empty ByteArray`() { fun `encode empty ByteArray`() {
val expected = ubyteArrayOf() val expected = byteArrayOf()
val actual = encoding.encode(ubyteArrayOf()) val actual = encoding.encode(byteArrayOf())
assertContentEquals(expected, actual) assertContentEquals(expected, actual)
} }
@Test @Test
fun `encode "Hello World!"`() { fun `encode "Hello World!"`() {
val expected = ubyteArrayOf( val expected = byteArrayOf(
0x30U, 0x31U, 0x30U, 0x30U, 0x31U, 0x30U, 0x30U, 0x30U, 0x30, 0x31, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30,
0x30U, 0x31U, 0x31U, 0x30U, 0x30U, 0x31U, 0x30U, 0x31U, 0x30, 0x31, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31,
0x30U, 0x31U, 0x31U, 0x30U, 0x31U, 0x31U, 0x30U, 0x30U, 0x30, 0x31, 0x31, 0x30, 0x31, 0x31, 0x30, 0x30,
0x30U, 0x31U, 0x31U, 0x30U, 0x31U, 0x31U, 0x30U, 0x30U, 0x30, 0x31, 0x31, 0x30, 0x31, 0x31, 0x30, 0x30,
0x30U, 0x31U, 0x31U, 0x30U, 0x31U, 0x31U, 0x31U, 0x31U, 0x30, 0x31, 0x31, 0x30, 0x31, 0x31, 0x31, 0x31,
0x30U, 0x30U, 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30U, 0x31U, 0x30U, 0x31U, 0x30U, 0x31U, 0x31U, 0x31U, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x31,
0x30U, 0x31U, 0x31U, 0x30U, 0x31U, 0x31U, 0x31U, 0x31U, 0x30, 0x31, 0x31, 0x30, 0x31, 0x31, 0x31, 0x31,
0x30U, 0x31U, 0x31U, 0x31U, 0x30U, 0x30U, 0x31U, 0x30U, 0x30, 0x31, 0x31, 0x31, 0x30, 0x30, 0x31, 0x30,
0x30U, 0x31U, 0x31U, 0x30U, 0x31U, 0x31U, 0x30U, 0x30U, 0x30, 0x31, 0x31, 0x30, 0x31, 0x31, 0x30, 0x30,
0x30U, 0x31U, 0x31U, 0x30U, 0x30U, 0x31U, 0x30U, 0x30U, 0x30, 0x31, 0x31, 0x30, 0x30, 0x31, 0x30, 0x30,
0x30U, 0x30U, 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x31U, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x31,
) )
val actual = encoding.encode(`Hello World!`) val actual = encoding.encode(`Hello World!`)
assertContentEquals(expected, actual) assertContentEquals(expected, actual)

View File

@@ -1,31 +1,33 @@
package com.infendro.encoding package com.infendro.encoding
import com.infendro.encoding.stream.Base32
import com.infendro.encoding.stream.StreamEncoding
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
class `Base32 Test` { class `Base32 Test` {
val encoding: Encoding val encoding: StreamEncoding
get() = Base32 get() = Base32
val `Hello World!` = ubyteArrayOf( val `Hello World!` = byteArrayOf(
0x48U, 0x65U, 0x6cU, 0x6cU, 0x48, 0x65, 0x6c, 0x6c,
0x6fU, 0x20U, 0x57U, 0x6fU, 0x6f, 0x20, 0x57, 0x6f,
0x72U, 0x6cU, 0x64U, 0x21U, 0x72, 0x6c, 0x64, 0x21,
) )
@Test @Test
fun `encode empty ByteArray`() { fun `encode empty ByteArray`() {
val expected = ubyteArrayOf() val expected = byteArrayOf()
val actual = encoding.encode(ubyteArrayOf()) val actual = encoding.encode(byteArrayOf())
assertContentEquals(expected, actual) assertContentEquals(expected, actual)
} }
@Test @Test
fun `encode "Hello World!"`() { fun `encode "Hello World!"`() {
val expected = ubyteArrayOf( val expected = byteArrayOf(
0x4aU, 0x42U, 0x53U, 0x57U, 0x59U, 0x33U, 0x44U, 0x50U, 0x4a, 0x42, 0x53, 0x57, 0x59, 0x33, 0x44, 0x50,
0x45U, 0x42U, 0x4cU, 0x57U, 0x36U, 0x34U, 0x54U, 0x4dU, 0x45, 0x42, 0x4c, 0x57, 0x36, 0x34, 0x54, 0x4d,
0x4dU, 0x51U, 0x51U, 0x51U, 0x3dU, 0x3dU, 0x3dU, 0x3dU, 0x4d, 0x51, 0x51, 0x51, 0x3d, 0x3d, 0x3d, 0x3d,
) )
val actual = encoding.encode(`Hello World!`) val actual = encoding.encode(`Hello World!`)
assertContentEquals(expected, actual) assertContentEquals(expected, actual)

View File

@@ -1,30 +1,32 @@
package com.infendro.encoding package com.infendro.encoding
import com.infendro.encoding.stream.Base64
import com.infendro.encoding.stream.StreamEncoding
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
class `Base64 Test` { class `Base64 Test` {
val encoding: Encoding val encoding: StreamEncoding
get() = Base64 get() = Base64
val `Hello World!` = ubyteArrayOf( val `Hello World!` = byteArrayOf(
0x48U, 0x65U, 0x6cU, 0x6cU, 0x48, 0x65, 0x6c, 0x6c,
0x6fU, 0x20U, 0x57U, 0x6fU, 0x6f, 0x20, 0x57, 0x6f,
0x72U, 0x6cU, 0x64U, 0x21U, 0x72, 0x6c, 0x64, 0x21,
) )
@Test @Test
fun `encode empty ByteArray`() { fun `encode empty ByteArray`() {
val expected = ubyteArrayOf() val expected = byteArrayOf()
val actual = encoding.encode(ubyteArrayOf()) val actual = encoding.encode(byteArrayOf())
assertContentEquals(expected, actual) assertContentEquals(expected, actual)
} }
@Test @Test
fun `encode "Hello World!"`() { fun `encode "Hello World!"`() {
val expected = ubyteArrayOf( val expected = byteArrayOf(
0x53U, 0x47U, 0x56U, 0x73U, 0x62U, 0x47U, 0x38U, 0x67U, 0x53, 0x47, 0x56, 0x73, 0x62, 0x47, 0x38, 0x67,
0x56U, 0x32U, 0x39U, 0x79U, 0x62U, 0x47U, 0x51U, 0x68U, 0x56, 0x32, 0x39, 0x79, 0x62, 0x47, 0x51, 0x68,
) )
val actual = encoding.encode(`Hello World!`) val actual = encoding.encode(`Hello World!`)
assertContentEquals(expected, actual) assertContentEquals(expected, actual)

View File

@@ -1,32 +1,34 @@
package com.infendro.encoding package com.infendro.encoding
import com.infendro.encoding.stream.Base8
import com.infendro.encoding.stream.StreamEncoding
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
class `Base8 Test` { class `Base8 Test` {
val encoding: Encoding val encoding: StreamEncoding
get() = Base8 get() = Base8
val `Hello World!` = ubyteArrayOf( val `Hello World!` = byteArrayOf(
0x48U, 0x65U, 0x6cU, 0x6cU, 0x48, 0x65, 0x6c, 0x6c,
0x6fU, 0x20U, 0x57U, 0x6fU, 0x6f, 0x20, 0x57, 0x6f,
0x72U, 0x6cU, 0x64U, 0x21U, 0x72, 0x6c, 0x64, 0x21,
) )
@Test @Test
fun `encode empty ByteArray`() { fun `encode empty ByteArray`() {
val expected = ubyteArrayOf() val expected = byteArrayOf()
val actual = encoding.encode(ubyteArrayOf()) val actual = encoding.encode(byteArrayOf())
assertContentEquals(expected, actual) assertContentEquals(expected, actual)
} }
@Test @Test
fun `encode "Hello World!"`() { fun `encode "Hello World!"`() {
val expected = ubyteArrayOf( val expected = byteArrayOf(
0x32U, 0x32U, 0x30U, 0x36U, 0x32U, 0x35U, 0x35U, 0x34U, 0x32, 0x32, 0x30, 0x36, 0x32, 0x35, 0x35, 0x34,
0x33U, 0x33U, 0x30U, 0x36U, 0x37U, 0x34U, 0x34U, 0x30U, 0x33, 0x33, 0x30, 0x36, 0x37, 0x34, 0x34, 0x30,
0x32U, 0x35U, 0x36U, 0x36U, 0x37U, 0x35U, 0x36U, 0x32U, 0x32, 0x35, 0x36, 0x36, 0x37, 0x35, 0x36, 0x32,
0x33U, 0x33U, 0x30U, 0x36U, 0x32U, 0x30U, 0x34U, 0x31U, 0x33, 0x33, 0x30, 0x36, 0x32, 0x30, 0x34, 0x31,
) )
val actual = encoding.encode(`Hello World!`) val actual = encoding.encode(`Hello World!`)
assertContentEquals(expected, actual) assertContentEquals(expected, actual)