implement Base45
This commit is contained in:
51
src/commonMain/kotlin/com/infendro/encoding/Base45.kt
Normal file
51
src/commonMain/kotlin/com/infendro/encoding/Base45.kt
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import com.infendro.encoding.exception.IllegalByteException
|
||||
|
||||
object Base45 : Encoding {
|
||||
private val alphabet: ByteArray = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".encodeToByteArray()
|
||||
private val base: Int = alphabet.size
|
||||
|
||||
override fun encode(bytes: ByteArray): ByteArray {
|
||||
val result = mutableListOf<Byte>()
|
||||
|
||||
for (i in bytes.indices step 2) {
|
||||
val remaining = minOf(bytes.size - i, 2)
|
||||
|
||||
var value = 0
|
||||
for (j in 0..<remaining) {
|
||||
val byte = bytes[i + j]
|
||||
value = (value shl 8) or (byte.toInt() and 0xFF)
|
||||
}
|
||||
|
||||
repeat(remaining + 1) {
|
||||
result += alphabet[value % base]
|
||||
value /= base
|
||||
}
|
||||
}
|
||||
|
||||
return result.toByteArray()
|
||||
}
|
||||
|
||||
override fun decode(bytes: ByteArray): ByteArray {
|
||||
val result = mutableListOf<Byte>()
|
||||
|
||||
for (i in bytes.indices step 3) {
|
||||
val remaining = minOf(bytes.size - i, 3)
|
||||
|
||||
var value = 0
|
||||
for (j in (0..<remaining).reversed()) {
|
||||
val byte = bytes[i + j]
|
||||
val index = alphabet.indexOf(byte)
|
||||
if (index == -1) throw IllegalByteException(byte)
|
||||
value = value * base + index
|
||||
}
|
||||
|
||||
for (j in (0..<(remaining - 1)).reversed()) {
|
||||
result += ((value shr (j * 8)) and 0xFF).toByte()
|
||||
}
|
||||
}
|
||||
|
||||
return result.toByteArray()
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base45.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base45.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base45 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base45
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "%69 VD82EI2B.KESTC".encodeToByteArray()
|
||||
|
||||
@Test
|
||||
fun `encode empty`() {
|
||||
val actual = encoding.encode(byteArrayOf())
|
||||
assertContentEquals(byteArrayOf(), actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `decode empty`() {
|
||||
val actual = encoding.decode(byteArrayOf())
|
||||
assertContentEquals(byteArrayOf(), actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encode() {
|
||||
val actual = encoding.encode(original)
|
||||
assertContentEquals(encoded, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decode() {
|
||||
val actual = encoding.decode(encoded)
|
||||
assertContentEquals(original, actual)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user