Implement some operations on variable-length quantities, at least including conversions from a normal number in the language to the binary representation of the variable-length quantity for that number, and vice versa. Any variants are acceptable.



Task

With above operations,

convert these two numbers 0x200000 (2097152 in decimal) and 0x1fffff (2097151 in decimal) into sequences of octets (an eight-bit byte); 
display these sequences of octets;
convert these sequences of octets back to numbers, and check that they are equal to original numbers.


Module Module1
 
    Function ToVlq(v As ULong) As ULong
        Dim array(8) As Byte
        Dim buffer = ToVlqCollection(v).SkipWhile(Function(b) b = 0).Reverse().ToArray
        buffer.CopyTo(array, 0)
        Return BitConverter.ToUInt64(array, 0)
    End Function
 
    Function FromVlq(v As ULong) As ULong
        Dim collection = BitConverter.GetBytes(v).Reverse()
        Return FromVlqCollection(collection)
    End Function
 
    Iterator Function ToVlqCollection(v As ULong) As IEnumerable(Of Byte)
        If v > Math.Pow(2, 56) Then
            Throw New OverflowException("Integer exceeds max value.")
        End If
 
        Dim index = 7
        Dim significantBitReached = False
        Dim mask = &H7FUL << (index * 7)
        While index >= 0
            Dim buffer = mask And v
            If buffer > 0 OrElse significantBitReached Then
                significantBitReached = True
                buffer >>= index * 7
                If index > 0 Then
                    buffer = buffer Or &H80
                End If
                Yield buffer
            End If
            mask >>= 7
            index -= 1
        End While
    End Function
 
    Function FromVlqCollection(vlq As IEnumerable(Of Byte)) As ULong
        Dim v = 0UL
        Dim significantBitReached = False
 
        Using enumerator = vlq.GetEnumerator
            Dim index = 0
            While enumerator.MoveNext
                Dim buffer = enumerator.Current
                If buffer > 0 OrElse significantBitReached Then
                    significantBitReached = True
                    v <<= 7
                    v = v Or (buffer And &H7FUL)
                End If
 
                index += 1
                If index = 8 OrElse (significantBitReached AndAlso (buffer And &H80) <> &H80) Then
                    Exit While
                End If
            End While
        End Using
 
        Return v
    End Function
 
    Sub Main()
        Dim values = {&H7FUL << 7 * 7, &H80, &H2000, &H3FFF, &H4000, &H200000, &H1FFFFF}
        For Each original In values
            Console.WriteLine("Original: 0x{0:X}", original)
 
            REM collection
            Dim seq = ToVlqCollection(original)
            Console.WriteLine("Sequence: 0x{0}", seq.Select(Function(b) b.ToString("X2")).Aggregate(Function(a, b) String.Concat(a, b)))
 
            Dim decoded = FromVlqCollection(seq)
            Console.WriteLine("Decoded: 0x{0:X}", decoded)
 
            REM ints
            Dim encoded = ToVlq(original)
            Console.WriteLine("Encoded: 0x{0:X}", encoded)
 
            decoded = FromVlq(encoded)
            Console.WriteLine("Decoded: 0x{0:X}", decoded)
 
            Console.WriteLine()
        Next
    End Sub
 
End Module