Below is a Base Conversion Class that will take in any number (up to around 2.4 billion digits (limited by string.substring's integer property)), It will convert from any base to any base (from 2-36 inclusive)
It does have some simple error handling such as if you enter a number that is incorrect for its base (ex: FF in base 15 and under), it will also throw an error if you enter a base lower than 2 or higher than 36.
This code does use the BigInteger class so .NET 4.0 is a requirement, you must also add a reference (as well as an import) to System.Numerics
Here are is an example of how to use this class:
Dim converter as New BaseConverter
Dim Number1Toconvert as Integer = 255
Dim currentBase as Byte = 10
Dim targetBase as Byte = 16
Console.Writeline(converter.Convert(currentBase,targetBase,Ctype(Number1Toconvert,String)))
Imports System.Numerics
Public Class BaseConverter
Dim numLetter As List(Of String) = New List(Of String) _
(New String() {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", _
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", _
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", _
"U", "V", "W", "X", "Y", "Z"})
'returns if the number is valid for the selected base (see above example) *outside of code*
Public Function IsValidNumBase(ByVal str1 As String, ByVal base As Byte) As Boolean
For x As Integer = 0 To str1.Length - 1
If Not (numLetter.Contains(str1.Substring(x, 1).ToUpper)) Or ((base - 1) < numLetter.IndexOf(str1.Substring(x, 1).ToUpper)) Then
Return False
End If
Next
Return True
End Function
Function Convert(ByVal base As Byte, ByVal convert_to As Byte, ByVal inputnumber As String) As String
'if the base or convert_to base are less than 2 or greater than 36, return:
If (base < 2 Or base > 36) Or (convert_to < 2 Or convert_to > 36) Then
Return "Invalid base"
End If
'If the value is non alphanumeric or is incorrect for its base (ex "FF" for base 15 and under) then we'll return this error:
If Not (IsValidNumBase(inputnumber, base)) Then
Return "Invalid Input"
End If
'if the current base and the base to convert into are the same, return numtoconvert
If base = convert_to Then
Return inputnumber
End If
Dim decvaltoconvert As BigInteger = 0
'convert into a decimal value before working w/ it
If (base = 10) Then
decvaltoconvert = CType(inputnumber, BigInteger)
Else
Dim place As Integer = 0
For x As Integer = inputnumber.Length - 1 To 0 Step -1
'only using integer because .substring will not accept a biginteger value, besides, if its over 2.4billion digits long, u don't want to use this program anyway.
decvaltoconvert += CType((numLetter.IndexOf(inputnumber.Substring(x, 1).ToUpper) * (BigInteger.Pow(base, CInt(place)))), BigInteger)
place += 1
Next
End If
'if the output base is base 10, no need to work with it further
If convert_to = 10 Then
Return decvaltoconvert.ToString
End If
'convert into the desired base
Dim returnstr As String = ""
While decvaltoconvert > 0
Dim tempval As BigInteger = 0
BigInteger.DivRem(decvaltoconvert, CType(convert_to, BigInteger), tempval) 'modulus division with the Biginteger class, sets tempval to the remainder
'Note that if u put tempval = .Divrem(....) then it sets tempval equal to decvaltoconvert / convert base, which is useless for what we need.
returnstr = String.Concat(returnstr, numLetter.Item(CType(tempval, Integer)))
decvaltoconvert = CType(BigInteger.Divide(decvaltoconvert, convert_to), BigInteger)
End While
returnstr = StrReverse(returnstr)
Return returnstr
End Function
End Class
Comments are welcome (and expected), I'd love to know how to improve the code! This is v2 of the code (before i was using select....case instead of the list... trimmed off nearly 180 lines of code when i switched to lists =)
for general purpose, the code runs near instantly (runs at 0ms) using stopwatch timer in system.diagnostics. Once you reach about 20,000 digits it starts to slow down quite a bit.
Test Results: (conversion from a string of x "z" into binary (so from max num base 36 to base 2)
At the times of these tests I did have firefox open, with 1 tab (on the page to type this up lol), vs2010 of course (im running in debug mode btw, not sure if release mode runs faster because of less overhead), alsong music player, trillian chat, notepad++ (for the string of "z", has a nice character count in it.
Running windows 7 ultimate 32bit, 3 GB RAM, 2.4GHz single core CPU.
Test : 500 "z"'s took 32ms
Test : 1000 "z"'s took 125ms
Test : 5000 "z"'s took 5038ms
Test : 10000 "z"'s took 29059ms
Test : 15000 "z"'s took 86625ms
Test : 20000 "z"'s took 203303ms
Now, to put that all into perspective, the first test (500 "z"'s in base 10 is:
1416610262383486172379625252491522441664047183091019132232354743214061894759648643634766
1333869287260068907949302029484915942402681211620694598046617844295512220793103312980549
5915371609590530279406241175980034175030157226974281761556003622631285675902995117766865
9286207437632823299032510124868012377691457648281509578456812298622189041183773757009886
4613342090972756469661488216176894465388028416768338495326989675118087222767384596111351
3049578690252738029782817837319299664682105792298300695566989289373425089883407923357377
4471937659850690897713529198311772264826917794715465769751707499344151552683988707340019
1797445153760221695723268255006134044062503100710134200414607696976757837002911389023284
338696251543694980946202137938610119300450795091488653253649628649410789375
^ 779 digit long number *wish I could see some of your jaws drop at that like mine did...
inserted some new lines so it didn't screw up the page.
When I made this I was in the code snippets forum, so I thought it would have been a submission there automatically...