Skip to content
Bluetape4k docs1.11

Encoding and data boundaries

Latest stable Based on Bluetape4k release 1.11.0

When binary values cross a text protocol, cache key, or diagnostic boundary, both sides must reconstruct the same bytes. Core codec helpers make nullable-input, UTF-8 string, URL-safe Base64, and Hex behavior explicit with a small API.

Encoding is not encryption. API keys and personal data remain secrets after Base64 or Hex encoding.

domain value -> choose charset -> bytes -> encode wire format -> text
text -> decode wire format -> bytes -> use the same charset -> domain value

The string/byte boundary chooses a charset. The byte/transport-text boundary chooses a format. Leaving either implicit is a common source of cross-language round-trip defects.

TaskAPIContract
Produce URL-safe Base64 textencodeBase64String()Uses Base64.getUrlEncoder()
Restore URL-safe Base64decodeBase64String()Uses Base64.getUrlDecoder()
Produce Hex textencodeHexString()Uses JDK HexFormat
Restore HexdecodeHexString()Propagates parser errors for malformed input
Handle nullable inputThe extensions aboveNormalizes null to empty bytes/text

URL-safe Base64 can use a different alphabet from MIME Base64. If an external protocol specifies padding or the standard alphabet, lock compatibility with its specification and fixture before integration.

import io.bluetape4k.codec.decodeBase64String
import io.bluetape4k.codec.decodeHexString
import io.bluetape4k.codec.encodeBase64String
import io.bluetape4k.codec.encodeHexString
val payload = "order:42"
val base64 = payload.encodeBase64String()
check(base64.decodeBase64String().toString(Charsets.UTF_8) == payload)
val hex = payload.encodeToByteArray().encodeHexString()
check(hex.decodeHexString().toString(Charsets.UTF_8) == payload)

String helpers include UTF-8 conversion. For binary protocols, stay on the ByteArray overloads rather than taking a detour through String; that avoids extra allocation and charset guessing.

RequirementPreferWhy
Binary in URLs, cookies, or compact text fieldsURL-safe Base64Shorter than Hex and URL-oriented alphabet
Checksums, short binary IDs, human-comparable dumpsHexLonger but easy to compare visually
Human-readable domain identifierAn explicit domain formatBase64/Hex carries no domain meaning
Confidentiality or integrityEncryption, signatures, and secret storageEncoding provides neither property

Base58, Base62, and Url62 have their own purposes. Do not select one merely because it looks shorter without a contract shared by both endpoints.

  • null and blank input normalize to an empty result. Validate before the codec when absence is an error.
  • Malformed Base64 and Hex propagate JDK decoder/parser failures.
  • Do not turn decoder failures into empty bytes; that conflates an empty payload with a damaged one.
  • Logging encoded data keeps the original data classification.
fun decodeExternalToken(encoded: String?): ByteArray {
val token = requireNotNull(encoded) { "token is required" }
return runCatching { token.decodeBase64String() }
.getOrElse { cause -> throw IllegalArgumentException("invalid token encoding", cause) }
}

Observe payload size, malformed-input counts, and protocol version. Consider a streaming codec when large payloads are repeatedly copied into byte arrays and strings. Cross-language contract tests should include ASCII, UTF-8, empty input, padding, and special-character fixtures.

Continue with Validation and invariants for boundary failures and Core recipes for an assembled flow.