How to encode and decode any string into Base‑36 in VB.NET

1 Answer

0 votes
Imports System
Imports System.Text
Imports System.Numerics

Module Base36Converter

    ''' <summary>
    ''' Encodes an arbitrary string into its Base-36 representation (Big-Endian).
    ''' </summary>
    Function EncodeToBase36(input As String) As String
        If String.IsNullOrEmpty(input) Then Return String.Empty

        ' Step 1: Convert string to UTF-8 bytes
        Dim bytes As Byte() = Encoding.UTF8.GetBytes(input)

        ' Step 2: Reverse bytes to convert from Big-Endian (String order) to Little-Endian (.NET BigInteger order)
        Array.Reverse(bytes)

        ' Step 3: Append a 0x00 byte at the end of the little-endian array to guarantee it's interpreted as positive
        Dim positiveBytes(bytes.Length) As Byte
        Array.Copy(bytes, positiveBytes, bytes.Length)
        Dim bigInt As New BigInteger(positiveBytes)

        ' Step 4: Extract Base-36 digits (least-significant to most-significant)
        Const Digits As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        Dim result As New StringBuilder()

        While bigInt > 0
            Dim remainder As BigInteger = 0
            bigInt = BigInteger.DivRem(bigInt, 36, remainder)
            result.Append(Digits(CInt(remainder)))
        End While

        ' Step 5: Reverse the accumulated digits to get the final Big-Endian Base-36 string
        Return ReverseString(result.ToString())
    End Function

    ''' <summary>
    ''' Decodes a Base-36 string back into its original text representation.
    ''' </summary>
    Function DecodeFromBase36(encoded As String) As String
        If String.IsNullOrEmpty(encoded) Then Return String.Empty

        Dim bigInt As BigInteger = 0
        Const Digits As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

        ' Step 1: Convert Base-36 string back to BigInteger
        For Each ch As Char In encoded.ToUpper()
            Dim value As Integer = Digits.IndexOf(ch)
            If value = -1 Then Throw New ArgumentException("Invalid Base-36 character.")
            bigInt = (bigInt * 36) + value
        Next

        ' Step 2: Get the little-endian byte array from BigInteger
        Dim bytes As Byte() = bigInt.ToByteArray()

        ' Trim any trailing zero bytes padded by BigInteger before reversing
        Dim actualLength As Integer = bytes.Length
        While actualLength > 0 AndAlso bytes(actualLength - 1) = 0
            actualLength -= 1
        End While

        ' Step 3: Reverse the bytes back to Big-Endian (original string byte order)
        Dim orderedBytes(actualLength - 1) As Byte
        Array.Copy(bytes, orderedBytes, actualLength)
        Array.Reverse(orderedBytes)

        ' Step 4: Convert bytes back to the original UTF-8 string
        Return Encoding.UTF8.GetString(orderedBytes)
    End Function

    Private Function ReverseString(s As String) As String
        Dim arr As Char() = s.ToCharArray()
        Array.Reverse(arr)
        Return New String(arr)
    End Function

    Sub Main()
        Dim text As String = "Hello Universe!"
        Dim encoded As String = EncodeToBase36(text)
        Dim decoded As String = DecodeFromBase36(encoded)

        Console.WriteLine("Original: " & text)
        Console.WriteLine("Base-36 encoded: " & encoded)
        Console.WriteLine("Decoded: " & decoded)
    End Sub

End Module

		
'
' run:
'
' Original: Hello Universe!
' Base-36 encoded: LP4N024HJ1YVBVD84Y8TYQP
' Decoded: Hello Universe!
'

 



answered 3 days ago by avibootz
...