refactor encodings

This commit is contained in:
2026-01-20 16:59:05 +01:00
parent 8290955755
commit 6283c2f44d
11 changed files with 83 additions and 154 deletions

View File

@@ -1,70 +1,80 @@
package com.infendro.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
class StreamEncoding internal constructor(
override val alphabet: ByteArray,
private val alphabet: ByteArray,
private val padding: Byte? = null,
) : Encoding {
private val base: Int = alphabet.size
private val bits: Int = log2(base).toInt()
private val block: Int = lcm(bits, 8) / bits
private val mask: Int = (0x01 shl bits) - 1
override fun encode(bytes: ByteArray): ByteArray {
val bits = log2(base).toInt()
val size = when (padding) {
null -> (bytes.size * 8).divCeil(bits)
else -> (bytes.size * 8).divCeil(bits).align(block)
}
val encoded = ByteArray(size)
var i = 0
val size = (bytes.size * 8).divCeil(bits)
val result = ByteArray(size)
var r = 0
var buffer = 0
var bufferBits = 0
for (i in bytes.indices) {
buffer = (buffer shl 8) + bytes[i]
for (byte in bytes) {
buffer = (buffer shl 8) or (byte.toInt() and 0xFF)
bufferBits += 8
while (bufferBits >= bits) {
val offset = bufferBits - bits
val index = (buffer ushr offset)
buffer = buffer and ((base - 1) shl offset).inv()
val index = (buffer shr (bufferBits - bits)) and mask
bufferBits -= bits
result[r++] = alphabet[index]
encoded[i++] = alphabet[index]
}
}
if (bufferBits > 0) {
val index = buffer shl (bits - bufferBits)
result[r] = alphabet[index]
val index = (buffer shl (bits - bufferBits)) and mask
encoded[i++] = alphabet[index]
}
return result
while (i < encoded.size) {
encoded[i++] = padding!!
}
return encoded
}
override fun decode(bytes: ByteArray): ByteArray {
val bits = log2(base).toInt()
val end = when (padding) {
null -> bytes.size
else -> when (val index = bytes.indexOf(padding)) {
-1 -> bytes.size
else -> index
}
}
val size = end * bits / 8
val decoded = ByteArray(size)
var i = 0
val size = bytes.size * bits / 8
val result = ByteArray(size)
var r = 0
var buffer = 0
var bufferBits = 0
for (i in bytes.indices) {
val byte = bytes[i]
val value = alphabet.indexOf(byte)
if (value == -1) throw IllegalByteException(byte)
buffer = (buffer shl bits) + value.toByte()
for (b in 0..<end) {
val byte = bytes[b]
val index = alphabet.indexOf(byte)
if (index == -1) throw IllegalByteException(byte)
buffer = (buffer shl bits) or index
bufferBits += bits
if (bufferBits >= 8) {
val offset = bufferBits - 8
val character = (buffer ushr offset).toByte()
buffer = buffer and (0xFF shl offset).inv()
val byte = (buffer shr (bufferBits - 8)) and 0xFF
bufferBits -= 8
result[r++] = character
decoded[i++] = byte.toByte()
}
}
return result
return decoded
}
}