Skip to content

Instantly share code, notes, and snippets.

@shmaltorhbooks
Last active February 28, 2025 15:42
Show Gist options
  • Save shmaltorhbooks/e5802107b6c88f42233313a2640c4f39 to your computer and use it in GitHub Desktop.
Save shmaltorhbooks/e5802107b6c88f42233313a2640c4f39 to your computer and use it in GitHub Desktop.
convert id between number systems
package org.timeout.app
import java.math.BigInteger
class NumberSystem(val alphabet: String = "0123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ") {
val base = alphabet.length.toBigInteger()
fun encode(input: String): String {
val number = BigInteger(1, input.toByteArray())
val encoded = StringBuilder()
var num = number
while (num > BigInteger.ZERO) {
val remainder = (num % base).toInt()
encoded.append(alphabet[remainder])
num /= base
}
return encoded.reverse().toString()
}
fun decode(input: String): String {
var num = BigInteger.ZERO
for (char in input) {
num = num * base + alphabet.indexOf(char).toBigInteger()
}
return String(num.toByteArray())
}
}
final readonly class NumberSystem
{
public function __construct(
private string $alphabet = '0123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ',
) {
}
public function encode(int $num): string
{
$baseCount = \strlen($this->alphabet);
$encoded = '';
while ($num >= $baseCount) {
$div = $num / $baseCount;
$mod = ($num - ($baseCount * (int)$div));
$encoded = $this->alphabet[$mod] . $encoded;
$num = (int)$div;
}
if ($num) {
$encoded = $this->alphabet[$num] . $encoded;
}
return $encoded;
}
public function decode(string $num): int
{
$decoded = 0;
$multi = 1;
while (\strlen($num) > 0) {
$digit = $num[\strlen($num) - 1];
$decoded += $multi * \strpos($this->alphabet, $digit);
$multi = $multi * \strlen($this->alphabet);
$num = \substr($num, 0, -1);
}
return $decoded;
}
}
package app
import org.junit.jupiter.api.Tag
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import kotlin.test.assertEquals
class NumberSystemTest {
@ParameterizedTest
@MethodSource("provideStrings")
@Tag("fast")
fun testConvert(alphabet: String, input: String, expectedString: String) {
val ns = NumberSystem(alphabet)
val encoded = ns.encode(input)
assertEquals(expectedString, ns.encode(input))
assertEquals(input, ns.decode(encoded))
}
companion object {
@JvmStatic
fun provideStrings() = listOf(
Arguments.of(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"bla",
"R40f",
),
Arguments.of(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"some text",
"ev7YMQpyQie4",
),
Arguments.of(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"youtube",
"2WY44DpVLR",
),
Arguments.of(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"very very very very very very long text",
"2PRZUWZ8V84hvg31WAmSsIg8afccqQeGwVnRuXizEyfE4MgXinf52",
),
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment