Skip to content
EignexPublic

About

kotlinx.serialization library that encodes data to short ASCII texts

Topics

Resources

Stars

44 stars

Watchers

2 watching

Forks

Repository files navigation

Eignex

KEncode

Maven Central Build codecov License

KEncode turns your data into short strings. It's useful when you need to fit data into a URL, a file name, a Kubernetes label, or anywhere else with a tight length limit.

There are three parts. ByteEncoding turns bytes into text. PackedFormat turns your Kotlin classes into as few bytes as possible. EncodedFormat does both, so you go straight from an object to a short string. If you want to know how it works, read the technical deep dive.

Installation

dependencies {
    implementation("com.eignex:kencode:1.4.0")
}

You also need the kotlinx.serialization plugin to use the formats.

Example

@Serializable
data class Payload(
    @PackedType(IntPacking.DEFAULT) val id: ULong, // varint
    @PackedType(IntPacking.SIGNED) val delta: Int, // zigzag
    val urgent: Boolean,    // 1 bit
    val handled: Instant?,  // 1 bit when null
    val type: PayloadType,  // 2 bits
)

enum class PayloadType { TYPE1, TYPE2, TYPE3 }

val payload = Payload(123u, -2, true, null, PayloadType.TYPE1)
val encoded = EncodedFormat.encodeToString(payload) // "00Xl1", 3 raw bytes
val decoded = EncodedFormat.decodeFromString<Payload>(encoded)

PackedFormat

PackedFormat stores booleans, nulls, and enums in just a few bits each. Numbers are stored in as few bytes as they need. Add PackedType to a field if it is often negative (SIGNED) or if you want a fixed size (FIXED).

val format = PackedFormat {
    defaultEncoding = IntPacking.FIXED
    serializersModule = myCustomModule
}
val bytes = format.encodeToByteArray(payload)

Fields are written in the order you declare them, with no names or tags. So if you change a class, old strings may no longer decode.

The encoded format only stays the same between patch versions. A new minor version may change it, so encode stored strings again after upgrading.

EncodedFormat

EncodedFormat serializes your object, optionally transforms the bytes, and then turns them into text. You can swap each step. For example, you can use ProtoBuf instead of PackedFormat, add a checksum, or pick a different codec.

val format = EncodedFormat {
    codec = Base36
    checksum = Crc16
    binaryFormat = ProtoBuf
}

val compacted = EncodedFormat {
    transform = CompactZeros.then(Crc16.asTransform())
}

You can also write your own transforms, like these examples for encryption and error correction.

Codecs

Every codec can be used on its own, and you can give it your own alphabet. Here is what the text "any byte data" (13 bytes) looks like in each:

Codec Output Length Alphabet
Base62 2BVj6VHhfNlsGmoMQF 18 [0-9A-Za-z]
Base36 0ksef5o4kvegb70nre15t 21 [0-9a-z]
Base64 YW55IGJ5dGUgZGF0YQ== 20 [0-9A-Za-z+/=]
Base85 @;^?5@X3',+Cno&@/ 17 ASCII 33–117

For even shorter strings, BaseRadix can use a large range of Unicode characters.

About

kotlinx.serialization library that encodes data to short ASCII texts

Topics

Resources

Stars

44 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages