45 lines
1.2 KiB
Kotlin
45 lines
1.2 KiB
Kotlin
package com.infendro.encoding.numeric
|
|
|
|
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) {
|
|
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 byte = bytes[i]
|
|
|
|
val index = alphabet.indexOf(byte)
|
|
if (index == -1) throw IllegalByteException(byte)
|
|
|
|
value = value.timesAdd(base, index)
|
|
}
|
|
|
|
return value.toByteArray()
|
|
}
|
|
}
|