implement composition

This commit is contained in:
2026-01-19 19:55:39 +01:00
parent 684b6d78ea
commit c1b8800e82
26 changed files with 91 additions and 68 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
package com.infendro.encoding.numeric
package com.infendro.encoding
private val alphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz".encodeToByteArray()
object Base56 : NumericEncoding(alphabet)
object Base56 : Encoding by NumericEncoding(alphabet)

View File

@@ -1,5 +1,5 @@
package com.infendro.encoding.numeric
package com.infendro.encoding
private val alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".encodeToByteArray()
object Base58 : NumericEncoding(alphabet)
object Base58 : Encoding by NumericEncoding(alphabet)

View File

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

View File

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

View File

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

View File

@@ -1,15 +1,10 @@
package com.infendro.encoding
abstract class Encoding(
val alphabet: ByteArray,
) {
init {
require(alphabet.isNotEmpty())
}
interface Encoding {
val alphabet: ByteArray
val base: Int
get() = alphabet.size
abstract fun encode(bytes: ByteArray): ByteArray
abstract fun decode(bytes: ByteArray): ByteArray
fun encode(bytes: ByteArray): ByteArray
fun decode(bytes: ByteArray): ByteArray
}

View File

@@ -1,22 +1,21 @@
package com.infendro.encoding.numeric
package com.infendro.encoding
import com.infendro.encoding.Encoding
import com.infendro.encoding.exception.IllegalByteException
import com.infendro.encoding.util.BigInt
import com.infendro.encoding.util.log2
import kotlin.math.ceil
open class NumericEncoding(
alphabet: ByteArray,
) : Encoding(alphabet) {
class NumericEncoding internal constructor(
override val alphabet: ByteArray,
) : Encoding {
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
var x = BigInt.from(bytes)
while (!x.isZero()) {
val (quotient, remainder) = x.divRem(base)
x = quotient

View File

@@ -1,16 +1,15 @@
package com.infendro.encoding.stream
package com.infendro.encoding
import com.infendro.encoding.Encoding
import com.infendro.encoding.exception.IllegalByteException
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,
class StreamEncoding internal constructor(
override val alphabet: ByteArray,
private val padding: Byte? = null,
) : Encoding(alphabet) {
) : Encoding {
init {
require(base and (base - 1) == 0)
}
@@ -30,7 +29,6 @@ open class StreamEncoding(
var r = 0
var buffer = 0
var bufferBits = 0
for (i in bytes.indices) {
buffer = (buffer shl 8) + bytes[i]
bufferBits += 8
@@ -71,7 +69,6 @@ open class StreamEncoding(
var r = 0
var buffer = 0
var bufferBits = 0
for (i in bytes.indices) {
val byte = bytes[i]
if (byte == padding) break

View File

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

View File

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

View File

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