Compare commits
28 Commits
2e44310edb
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
841bdfa21e
|
|||
|
e08cbb0fa9
|
|||
|
61d6a8e191
|
|||
|
6283c2f44d
|
|||
|
8290955755
|
|||
|
c1b8800e82
|
|||
|
684b6d78ea
|
|||
|
24c667bc9c
|
|||
|
a347bd617c
|
|||
|
a553aa6723
|
|||
|
83fd77c8ee
|
|||
|
456f33f2d9
|
|||
|
55faf1d670
|
|||
|
45d74d9cff
|
|||
|
688beb61b9
|
|||
|
21858641e5
|
|||
|
704cf2a796
|
|||
| bd5d904a3b | |||
|
843013b7e7
|
|||
|
e40ef3168d
|
|||
|
9e4109c9f3
|
|||
|
12344283f7
|
|||
|
52a1ca6553
|
|||
|
71a47af43c
|
|||
|
08a79efa04
|
|||
|
9655235a10
|
|||
|
5b96f19eef
|
|||
|
4042a8e086
|
@@ -1,36 +0,0 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
GIT__TOKEN: ${{ secrets.TOKEN }}
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: linux
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/cache/restore@v4
|
||||
with:
|
||||
key: gradle
|
||||
path: |
|
||||
~/.gradle/caches/
|
||||
~/.gradle/wrapper/
|
||||
~/.konan/
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '24'
|
||||
distribution: 'temurin'
|
||||
|
||||
- run: ./gradlew publish
|
||||
|
||||
- uses: actions/cache/save@v4
|
||||
with:
|
||||
key: gradle
|
||||
path: |
|
||||
~/.gradle/caches/
|
||||
~/.gradle/wrapper/
|
||||
~/.konan/
|
||||
47
.gitea/workflows/publish.yaml
Normal file
47
.gitea/workflows/publish.yaml
Normal file
@@ -0,0 +1,47 @@
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: linux
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '24'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Cache Gradle
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: gradle-${{ hashFiles('**/libs.versions.toml') }}
|
||||
restore-keys: gradle
|
||||
path: |
|
||||
~/.gradle/caches/
|
||||
~/.gradle/wrapper/
|
||||
|
||||
- name: Cache Konan
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: konan-${{ hashFiles('**/libs.versions.toml') }}
|
||||
restore-keys: konan
|
||||
path: |
|
||||
~/.konan/
|
||||
|
||||
- name: Cache Node
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: node-${{ hashFiles('**/libs.versions.toml') }}
|
||||
restore-keys: node
|
||||
path: |
|
||||
~/.gradle/nodejs
|
||||
~/.gradle/yarn
|
||||
|
||||
- name: Publish
|
||||
run: ./gradlew publish
|
||||
env:
|
||||
INFENDRO__TOKEN: ${{ secrets.TOKEN }}
|
||||
28
.gitea/workflows/test.yaml
Normal file
28
.gitea/workflows/test.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: linux
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '24'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Cache Gradle
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: gradle-${{ hashFiles('**/libs.versions.toml') }}
|
||||
restore-keys: gradle
|
||||
path: |
|
||||
~/.gradle/caches/
|
||||
~/.gradle/wrapper/
|
||||
|
||||
- name: Test
|
||||
run: ./gradlew jvmTest
|
||||
44
README.md
Normal file
44
README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# encoding-kt
|
||||
|
||||
`encoding-kt` is a Kotlin Multiplatform library that provides common `ByteArray` encodings.
|
||||
|
||||
Supported encodings:
|
||||
- Base2 (binary)
|
||||
- Base8 (octal)
|
||||
- Base10 (decimal)
|
||||
- Base16 (hexadecimal, uppercase/lowercase)
|
||||
- Base32
|
||||
- Base36
|
||||
- Base45
|
||||
- Base56
|
||||
- Base58
|
||||
- Base62
|
||||
- Base64 (standard/URL)
|
||||
|
||||
## Installation
|
||||
|
||||
Add the following to your `build.gradle.kts`.
|
||||
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://git.infendro.com/api/packages/Infendro/maven")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.infendro:encoding:1.3.0")
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```kotlin
|
||||
fun main() {
|
||||
// the string to encode
|
||||
val test = "Hello World!".encodeToByteArray()
|
||||
|
||||
// encode the string with the desired encoding
|
||||
val encoded = Base16.encode(test).decodeToString()
|
||||
|
||||
println(encoded) // 48656C6C6F20576F726C6421
|
||||
}
|
||||
```
|
||||
@@ -1,48 +1,40 @@
|
||||
group = "com.infendro"
|
||||
version = "1.1.0"
|
||||
@file:OptIn(ExperimentalWasmDsl::class)
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
import com.infendro.plugin.infendro
|
||||
import com.infendro.plugin.token
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
|
||||
group = "com.infendro"
|
||||
version = "1.3.0"
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.infendro)
|
||||
alias(libs.plugins.multiplatform)
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
js {
|
||||
nodejs()
|
||||
}
|
||||
linuxX64()
|
||||
}
|
||||
linuxArm64()
|
||||
mingwX64()
|
||||
macosX64()
|
||||
macosArm64()
|
||||
js { nodejs() }
|
||||
wasmJs { nodejs() }
|
||||
wasmWasi { nodejs() }
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url = uri("https://git.infendro.com/api/packages/Infendro/maven")
|
||||
authentication.create("header", HttpHeaderAuthentication::class)
|
||||
credentials(HttpHeaderCredentials::class) {
|
||||
val token = secret("git.token") ?: throw GradleException()
|
||||
|
||||
name = "Authorization"
|
||||
value = "token $token"
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonTest.dependencies {
|
||||
implementation(libs.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun secret(
|
||||
key: String,
|
||||
): String? {
|
||||
val property = key
|
||||
val environment = key
|
||||
.uppercase()
|
||||
.replace(".", "__")
|
||||
|
||||
val prop = properties[property] as String?
|
||||
val env = System.getenv(environment)
|
||||
|
||||
return prop ?: env
|
||||
publishing.repositories {
|
||||
infendro(token)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
[versions]
|
||||
kotlin = "2.1.20"
|
||||
infendro = "1.0.0"
|
||||
kotlin = "2.3.0"
|
||||
|
||||
[plugins]
|
||||
infendro = { id = "com.infendro.plugin", version.ref = "infendro" }
|
||||
multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||
|
||||
[libraries]
|
||||
test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,7 @@
|
||||
#Sun May 18 00:11:37 CEST 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
47
gradlew
vendored
47
gradlew
vendored
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -80,13 +82,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -114,7 +114,7 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -133,22 +133,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -193,18 +200,28 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
||||
41
gradlew.bat
vendored
41
gradlew.bat
vendored
@@ -13,8 +13,10 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +27,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -56,32 +59,34 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
rootProject.name = "encoding"
|
||||
|
||||
pluginManagement.repositories {
|
||||
maven("https://git.infendro.com/api/packages/Infendro/maven")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base10.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base10.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "0123456789".encodeToByteArray()
|
||||
|
||||
object Base10 : Encoding by NumericEncoding(alphabet)
|
||||
10
src/commonMain/kotlin/com/infendro/encoding/Base16.kt
Normal file
10
src/commonMain/kotlin/com/infendro/encoding/Base16.kt
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val uppercase = "0123456789ABCDEF".encodeToByteArray()
|
||||
private val lowercase = "0123456789abcdef".encodeToByteArray()
|
||||
|
||||
object Base16 : Encoding by StreamEncoding(uppercase) {
|
||||
val UPPERCASE = this
|
||||
|
||||
object LOWERCASE : Encoding by StreamEncoding(lowercase)
|
||||
}
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base2.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base2.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "01".encodeToByteArray()
|
||||
|
||||
object Base2 : Encoding by StreamEncoding(alphabet)
|
||||
@@ -1,31 +1,6 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
object Base32 : Encoding() {
|
||||
private val CHARACTERS = arrayOf<Byte>(
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
)
|
||||
private const val PADDING: Byte = 0x3d
|
||||
private val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".encodeToByteArray()
|
||||
private const val padding = '='.code.toByte()
|
||||
|
||||
override fun encode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return encode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
PADDING,
|
||||
)
|
||||
}
|
||||
|
||||
override fun decode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return decode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
PADDING,
|
||||
)
|
||||
}
|
||||
}
|
||||
object Base32 : Encoding by StreamEncoding(alphabet, padding)
|
||||
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base36.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base36.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".encodeToByteArray()
|
||||
|
||||
object Base36 : Encoding by NumericEncoding(alphabet)
|
||||
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()
|
||||
}
|
||||
}
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base56.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base56.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz".encodeToByteArray()
|
||||
|
||||
object Base56 : Encoding by NumericEncoding(alphabet)
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base58.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base58.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".encodeToByteArray()
|
||||
|
||||
object Base58 : Encoding by NumericEncoding(alphabet)
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base62.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base62.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".encodeToByteArray()
|
||||
|
||||
object Base62 : Encoding by NumericEncoding(alphabet)
|
||||
@@ -1,35 +1,11 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
object Base64 : Encoding() {
|
||||
private val CHARACTERS = arrayOf<Byte>(
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
||||
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f,
|
||||
)
|
||||
private const val PADDING: Byte = 0x3d
|
||||
private val standard = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".encodeToByteArray()
|
||||
private val url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".encodeToByteArray()
|
||||
private const val padding = '='.code.toByte()
|
||||
|
||||
override fun encode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return encode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
PADDING,
|
||||
)
|
||||
}
|
||||
object Base64 : Encoding by StreamEncoding(standard, padding) {
|
||||
val STANDARD = this
|
||||
|
||||
override fun decode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return decode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
PADDING,
|
||||
)
|
||||
}
|
||||
object URL : Encoding by StreamEncoding(url)
|
||||
}
|
||||
|
||||
5
src/commonMain/kotlin/com/infendro/encoding/Base8.kt
Normal file
5
src/commonMain/kotlin/com/infendro/encoding/Base8.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
private val alphabet = "01234567".encodeToByteArray()
|
||||
|
||||
object Base8 : Encoding by StreamEncoding(alphabet)
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
object Binary : Encoding() {
|
||||
private val CHARACTERS = arrayOf<Byte>(
|
||||
0x30, 0x31,
|
||||
)
|
||||
|
||||
override fun encode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return encode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
)
|
||||
}
|
||||
|
||||
override fun decode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return decode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,92 +1,6 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import com.infendro.encoding.util.lcm
|
||||
import com.infendro.encoding.util.log2
|
||||
import kotlin.math.pow
|
||||
|
||||
sealed class Encoding {
|
||||
abstract fun encode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray
|
||||
|
||||
abstract fun decode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray
|
||||
|
||||
protected fun encode(
|
||||
bytes: ByteArray,
|
||||
characters: Array<Byte>,
|
||||
padding: Byte? = null,
|
||||
): ByteArray {
|
||||
val length = log2(characters.size).toInt()
|
||||
val mask = (2.0.pow(length) - 1).toUInt()
|
||||
|
||||
val encoded = mutableListOf<Byte>()
|
||||
|
||||
var buffer = 0U
|
||||
var bits = 0
|
||||
|
||||
for (byte in bytes) {
|
||||
buffer = (buffer shl 8) + byte.toUByte()
|
||||
bits += 8
|
||||
|
||||
while (bits >= length) {
|
||||
val offset = bits - length
|
||||
val index = (buffer shr offset).toInt()
|
||||
buffer = buffer and (mask shl offset).inv()
|
||||
bits -= length
|
||||
|
||||
encoded.add(characters[index])
|
||||
}
|
||||
}
|
||||
if (bits > 0) {
|
||||
buffer = buffer shl (length - bits)
|
||||
val index = buffer.toInt()
|
||||
encoded.add(characters[index])
|
||||
}
|
||||
|
||||
if (padding != null) {
|
||||
val block = lcm(length, 8) / length
|
||||
while (encoded.size % block != 0) {
|
||||
encoded.add(padding)
|
||||
}
|
||||
}
|
||||
|
||||
return encoded.toByteArray()
|
||||
}
|
||||
|
||||
protected fun decode(
|
||||
bytes: ByteArray,
|
||||
characters: Array<Byte>,
|
||||
padding: Byte? = null,
|
||||
): ByteArray {
|
||||
val length = log2(characters.size).toInt()
|
||||
val mask = 0xFFU
|
||||
|
||||
val decoded = mutableListOf<Byte>()
|
||||
|
||||
var buffer = 0U
|
||||
var bits = 0
|
||||
|
||||
for (byte in bytes) {
|
||||
if (byte == padding) break
|
||||
|
||||
val index = characters.indexOf(byte)
|
||||
if (index == -1) throw Exception()
|
||||
|
||||
buffer = (buffer shl length) + index.toUByte()
|
||||
bits += length
|
||||
|
||||
if (bits >= 8) {
|
||||
val offset = bits - 8
|
||||
val character = (buffer shr offset).toByte()
|
||||
buffer = buffer and (mask shl offset).inv()
|
||||
bits -= 8
|
||||
|
||||
decoded.add(character)
|
||||
}
|
||||
}
|
||||
|
||||
return decoded.toByteArray()
|
||||
}
|
||||
interface Encoding {
|
||||
fun encode(bytes: ByteArray): ByteArray
|
||||
fun decode(bytes: ByteArray): ByteArray
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
object Hex : Encoding() {
|
||||
private val CHARACTERS = arrayOf<Byte>(
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
||||
)
|
||||
|
||||
override fun encode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return encode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
)
|
||||
}
|
||||
|
||||
override fun decode(
|
||||
bytes: ByteArray,
|
||||
): ByteArray {
|
||||
return decode(
|
||||
bytes,
|
||||
CHARACTERS,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import com.infendro.encoding.exception.IllegalByteException
|
||||
import com.infendro.encoding.util.BigInt
|
||||
|
||||
class NumericEncoding internal constructor(
|
||||
private val alphabet: ByteArray,
|
||||
) : Encoding {
|
||||
private val base: Int = alphabet.size
|
||||
|
||||
override fun encode(bytes: ByteArray): ByteArray {
|
||||
if (bytes.isEmpty()) return byteArrayOf()
|
||||
|
||||
val result = mutableListOf<Byte>()
|
||||
|
||||
var x = BigInt.from(bytes)
|
||||
while (!x.isZero()) {
|
||||
val (quotient, remainder) = x.divRem(base)
|
||||
x = quotient
|
||||
result += alphabet[remainder]
|
||||
}
|
||||
|
||||
return result.asReversed().toByteArray()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +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(
|
||||
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 size = when (padding) {
|
||||
null -> (bytes.size * 8).divCeil(bits)
|
||||
else -> (bytes.size * 8).divCeil(bits).align(block)
|
||||
}
|
||||
val encoded = ByteArray(size)
|
||||
var i = 0
|
||||
|
||||
var buffer = 0
|
||||
var bufferBits = 0
|
||||
for (byte in bytes) {
|
||||
buffer = (buffer shl 8) or (byte.toInt() and 0xFF)
|
||||
bufferBits += 8
|
||||
|
||||
while (bufferBits >= bits) {
|
||||
val index = (buffer shr (bufferBits - bits)) and mask
|
||||
bufferBits -= bits
|
||||
encoded[i++] = alphabet[index]
|
||||
}
|
||||
}
|
||||
if (bufferBits > 0) {
|
||||
val index = (buffer shl (bits - bufferBits)) and mask
|
||||
encoded[i++] = alphabet[index]
|
||||
}
|
||||
|
||||
while (i < encoded.size) {
|
||||
encoded[i++] = padding!!
|
||||
}
|
||||
|
||||
return encoded
|
||||
}
|
||||
|
||||
override fun decode(bytes: ByteArray): ByteArray {
|
||||
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
|
||||
|
||||
var buffer = 0
|
||||
var bufferBits = 0
|
||||
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 byte = (buffer shr (bufferBits - 8)) and 0xFF
|
||||
bufferBits -= 8
|
||||
decoded[i++] = byte.toByte()
|
||||
}
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.infendro.encoding.exception
|
||||
|
||||
abstract class DecodeException : Exception() {
|
||||
abstract override val message: String
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.infendro.encoding.exception
|
||||
|
||||
class IllegalByteException(
|
||||
val byte: Byte,
|
||||
) : DecodeException() {
|
||||
override val message: String
|
||||
get() {
|
||||
val hex = "0x${byte.toHexString().padStart(2, '0')}"
|
||||
val char = "'${byte.toInt().toChar()}'"
|
||||
return "Illegal byte $hex ($char)."
|
||||
}
|
||||
}
|
||||
73
src/commonMain/kotlin/com/infendro/encoding/util/BigInt.kt
Normal file
73
src/commonMain/kotlin/com/infendro/encoding/util/BigInt.kt
Normal file
@@ -0,0 +1,73 @@
|
||||
package com.infendro.encoding.util
|
||||
|
||||
internal class BigInt private constructor(
|
||||
val words: IntArray,
|
||||
) {
|
||||
init {
|
||||
require(words.isNotEmpty())
|
||||
}
|
||||
|
||||
fun isZero(): Boolean = words.all { it == 0 }
|
||||
|
||||
fun timesAdd(multiplier: Int, addend: Int): BigInt {
|
||||
val product = IntArray(words.size)
|
||||
var carry = addend
|
||||
|
||||
for (i in words.indices) {
|
||||
val current = (words[i].toLong() and 0xFFFFFFFFL) * multiplier + carry
|
||||
product[i] = current.toInt()
|
||||
carry = (current ushr 32).toInt()
|
||||
}
|
||||
|
||||
when {
|
||||
carry > 0 -> {
|
||||
val expanded = product.copyOf(product.size + 1)
|
||||
expanded[product.size] = carry
|
||||
return BigInt(expanded)
|
||||
}
|
||||
else -> return BigInt(product)
|
||||
}
|
||||
}
|
||||
|
||||
fun divRem(divisor: Int): Pair<BigInt, Int> {
|
||||
val quotient = IntArray(words.size)
|
||||
var remainder = 0
|
||||
|
||||
for (i in words.indices.reversed()) {
|
||||
val current = (remainder.toLong() shl 32) or (words[i].toLong() and 0xFFFFFFFFL)
|
||||
quotient[i] = (current / divisor.toLong()).toInt()
|
||||
remainder = (current % divisor.toLong()).toInt()
|
||||
}
|
||||
|
||||
when {
|
||||
quotient.size > 1 && quotient.last() == 0 -> {
|
||||
val contracted = quotient.copyOfRange(0, quotient.size - 1)
|
||||
return Pair(BigInt(contracted), remainder)
|
||||
}
|
||||
else -> return Pair(BigInt(quotient), remainder)
|
||||
}
|
||||
}
|
||||
|
||||
fun toByteArray(): ByteArray {
|
||||
val bytes = ByteArray((words.size * 4) - words.last().countLeadingZeroBytes())
|
||||
for (i in bytes.indices) {
|
||||
val (wi, bi) = (bytes.lastIndex - i).divRem(4)
|
||||
bytes[i] = (words[wi] ushr (bi * 8)).toByte()
|
||||
}
|
||||
return bytes
|
||||
}
|
||||
|
||||
companion object {
|
||||
val zero: BigInt
|
||||
get() = BigInt(intArrayOf(0))
|
||||
|
||||
fun from(bytes: ByteArray): BigInt {
|
||||
val words = IntArray(bytes.size.divCeil(4))
|
||||
for (i in bytes.indices) {
|
||||
val (wi, bi) = (bytes.lastIndex - i).divRem(4)
|
||||
words[wi] = words[wi] or ((bytes[i].toInt() and 0xFF) shl (bi * 8))
|
||||
}
|
||||
return BigInt(words)
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/commonMain/kotlin/com/infendro/encoding/util/Int.kt
Normal file
7
src/commonMain/kotlin/com/infendro/encoding/util/Int.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package com.infendro.encoding.util
|
||||
|
||||
fun Int.divRem(divisor: Int): Pair<Int, Int> =
|
||||
Pair(this / divisor, this % divisor)
|
||||
|
||||
fun Int.countLeadingZeroBytes(): Int =
|
||||
countLeadingZeroBits() / 8
|
||||
@@ -2,17 +2,16 @@ package com.infendro.encoding.util
|
||||
|
||||
import kotlin.math.log2
|
||||
|
||||
internal fun log2(
|
||||
value: Int,
|
||||
): Double {
|
||||
val x = value.toDouble()
|
||||
return log2(x)
|
||||
}
|
||||
internal fun Int.divCeil(n: Int): Int =
|
||||
(this + n - 1) / n
|
||||
|
||||
internal fun gcd(
|
||||
a: Int,
|
||||
b: Int,
|
||||
): Int {
|
||||
internal fun Int.align(n: Int): Int =
|
||||
divCeil(n) * n
|
||||
|
||||
internal fun log2(value: Int): Double =
|
||||
log2(value.toDouble())
|
||||
|
||||
internal fun gcd(a: Int, b: Int): Int {
|
||||
var x = a
|
||||
var y = b
|
||||
while (y != 0) {
|
||||
@@ -23,9 +22,6 @@ internal fun gcd(
|
||||
return x
|
||||
}
|
||||
|
||||
internal fun lcm(
|
||||
a: Int,
|
||||
b: Int,
|
||||
): Int {
|
||||
internal fun lcm(a: Int, b: Int): Int {
|
||||
return (a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base10.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base10.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base10 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base10
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "22405534230753928650781647905".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base16.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base16.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base16 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base16
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "48656C6C6F20576F726C6421".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base2.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base2.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base2 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base2
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "010010000110010101101100011011000110111100100000010101110110111101110010011011000110010000100001".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base32.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base32.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base32 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base32
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "JBSWY3DPEBLW64TMMQQQ====".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base36.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base36.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base36 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base36
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "2678LX5GVMSV1DRO9B5".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)
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base56.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base56.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base56 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base56
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "4Q9SNpVv4JrdwvjKj".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base58.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base58.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base58 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base58
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "2NEpo7TZRRrLZSi2U".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base62.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base62.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base62 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base62
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "T8dgcjRGkZ3aysdN".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base64.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base64.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base64 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base64
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "SGVsbG8gV29ybGQh".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)
|
||||
}
|
||||
}
|
||||
36
src/commonTest/kotlin/com/infendro/encoding/Base8.kt
Normal file
36
src/commonTest/kotlin/com/infendro/encoding/Base8.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.infendro.encoding
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
|
||||
class `Base8 Test` {
|
||||
val encoding: Encoding
|
||||
get() = Base8
|
||||
|
||||
val original = "Hello World!".encodeToByteArray()
|
||||
val encoded = "22062554330674402566756233062041".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