Page 1 of 1

Base10 to Base...

Posted: Wed May 25, 2011 8:06 pm
by jeslar360
I am not sure how many of you will find these functions useful, but I am posting them anyway. I know there are built in functions for converting back and forth from Hex/Base64/Base2(Binary)...but these functions seem to be very unfriendly to variables.

So, I designed these 2 procedures for converting back and forth...as well as some examples on usage...

First, converting to a base...I did this so there could be other bases besides the ones listed above...

Code: Select all

#_NUM_BASE_10   = "0123456789" ; This is just to give it a default

Procedure.s Int2Base(InVal.l, Valid.s=#_NUM_BASE_10)
  Base.l = Len(Valid)
  RemVal = InVal
  OutVal.s
  While RemVal
    OutVal = Mid(Valid, ((RemVal % Base) + 1), 1) + OutVal
    RemVal = ((RemVal-(RemVal % Base)) / Base)
  Wend
  If Not OutVal
    OutVal = "0"
  EndIf
  ProcedureReturn(OutVal)
EndProcedure
Then converting from any base back to Base 10 (regular integer)...

Code: Select all

#_NUM_BASE_10   = "0123456789" ; This is just to give it a default

Procedure.l Base2Int(InVal.s, Valid.s=#_NUM_BASE_10, UseCase=#False)
  Base.l = Len(Valid)
  If Not UseCase
    Valid = UCase(Valid)
    InVal = UCase(InVal)
    Debug "Not Case Sensitive"
  EndIf
  For i = 1 To Len(InVal)
    Chk.s   = Mid(InVal, i, 1)
    Pos     = FindString(Valid, Chk, 1)
    If Not Pos
      Debug "ERROR: Unsupported Character at Position " + Str(i)
      Break
    Else
      OutVal = (OutVal * Base) + (Pos - 1)
    EndIf
  Next
  ProcedureReturn(OutVal)
EndProcedure
And here, are some examples of how to use the functions in other functions...

I am showing Hex and Base64...just for examples

Code: Select all

#_NUM_BASE_16   = "0123456789ABCDEF"
#_NUM_BASE_64   = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"

Procedure Hex2Int(HexIn.s)
  ProcedureReturn(Base2Int(HexIn, #_NUM_BASE_16))
EndProcedure

Procedure.s Int2Hex(InVal)
  ProcedureReturn(Int2Base(InVal, #_NUM_BASE_16))
EndProcedure

Procedure Base64ToInt(B64In.s)
  ProcedureReturn(Base2Int(B64In, #_NUM_BASE_64, #True)) 
EndProcedure

Procedure.s Int2Base64(InVal)
  ProcedureReturn(Int2Base(InVal, #_NUM_BASE_64))
EndProcedure
The 3rd parameter in Base2Int is #False by default, that means Case Insensitive. That is fine for HEX, and BIN, but not for Base64...so we need to set the Case Sensitive to #True

Re: Base10 to Base...

Posted: Wed May 25, 2011 9:13 pm
by skywalk
Get the heck outta here? I just wrote this last night. :cry:
Thanks, your Base2Int approach is a bit faster as I was starting from the right side of the number to convert.
Then I was using the dreaded Pow() function in an integer expression and fought for an hour before I added a "0.0 + " in front. Then the calc worked correctly.

Code: Select all

#alphanum36$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Procedure.s SF_NumToBase36(x.i)
  ; Convert positive integer to base36 string.
  Protected.s r$
  If x > 0
    While x <> 0
      r$ = Mid(#alphanum36$, (x % 36) + 1, 1) + r$
      x / 36
    Wend
  Else
    r$ = "0"
  EndIf
  ProcedureReturn r$
EndProcedure

Procedure.i SF_Base36ToNum(base$)
  ; Convert base36 string to positive integer.
  Protected.i i, x, blen
  x = FindString(#alphanum36$, Right(base$, 1)) - 1  ; get last character
  blen = Len(base$)
  For i = blen - 1 To 1 Step -1
    x = 0.0 + x + Pow(36, (blen - i)) * (FindString(#alphanum36$, Mid(base$, i, 1)) - 1)
    ;   Must use "0.0 + " to force a double calc. Otherwise, wrong result!
  Next i
  ProcedureReturn x
EndProcedure
Debug SF_NumToBase36(100)  ; 2S
Debug SF_Base36ToNum("2S") ; 100

Re: Base10 to Base...

Posted: Thu May 26, 2011 12:43 am
by jeslar360
I completely understand the frustration. This is actually my 3rd time writing a base converter...the code from the last two got lost...they were all locked to a specific base (Hex, and Bin)...I thought to make it this way this time, because I knew I would be doing a lot of back and forth encoding between multiple bases in the near future, and wanted to take the Write It Once, Use It For Everything approach.

The problem is, its the SIMPLE things that are often overlooked, because we (as humans) tend to think "It can't be THAT simple!"

But it is quite true, that the simplest approach is often the best...so figured I would share my moment of insight with everyone :)

Re: Base10 to Base...

Posted: Sat Jun 25, 2011 12:13 pm
by jamba
cool, thanks for sharing!