'Traducido de http://solutionmania.com/blog/2011/8/7/base32-encoding-and-decoding-in-vbnet/
Sub Class_Globals
Dim const cBase32Alphabet As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
Dim const cBase32Pad As String = "="
Dim jo As JavaObject
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
jo.InitializeNewInstance(Application.PackageName & ".base32", Null)
End Sub
Sub TestBase32()
Dim i As Int
Dim j As Int
Dim Output() As Byte
For i = 104 To 0 Step -1
Dim Bytes(i) As Byte
For j = 0 To i - 1
Bytes(j) = 255 - i + j
Next
Output = base32decode(base32encode(Bytes, True))
If Bytes.Length <> Output.Length Then
Log("Old Length = " & Bytes.Length & ", New Length = " & Output.Length)
Return
End If
For j = 0 To i - 1
If Bytes(j) <> Output(j) Then
Log("Old Byte(" & j & ") = " & Bytes(j) & ", New Length = " & Output(j))
Return
End If
Next
Next
Log("TestBase32 OK")
End Sub
Sub base32encode(data() As Byte, includePadding As Boolean) As String
Dim RetVal As String = ""
Dim Segments As List
Dim x As Int
Segments.Initialize
' Divide the input data into 5 byte segments
Dim Index As Int = 0
Do While Index < data.Length
Dim CurrentSegment As Long = 0
Dim SegmentSize As Int = 0
Do While Index < data.Length And SegmentSize < 5
CurrentSegment = jo.RunMethod("BitRotI",Array(CurrentSegment,8))
CurrentSegment = CurrentSegment + Bit.And(data(Index),0xFF)
Index = Index + 1
SegmentSize = SegmentSize + 1
Loop
' If the size of the last segment was less than 5 bytes, pad with zeros
'CurrentSegment <<= (8 * (5 - SegmentSize))
CurrentSegment = jo.RunMethod("BitRotI",Array(CurrentSegment,(8 * (5 - SegmentSize))))
Segments.Add(CurrentSegment)
Loop
' Convert each 5 byte segment into 8 character strings
For Each CurrentSegment As Long In Segments
For x = 0 To 7
Dim i As Long = jo.RunMethod("BitRotD",Array(CurrentSegment, (7 - x) * 5))
Dim l As Long = 0x1F
RetVal = RetVal & cBase32Alphabet.Charat(jo.RunMethod("BitAnd",Array(i,l)))
Next
Next
' Correct the end of the string (where the input wasn't a multiple of 5 bytes)
Dim LastSegmentUsefulDataLength As Int = Utiles_VB.CInt(Ceil((data.Length Mod 5) * 8 / 5))
If LastSegmentUsefulDataLength = 0 Then
LastSegmentUsefulDataLength = 8
End If
RetVal = Utiles_VB.Mid(RetVal, 1, RetVal.Length - (8 - LastSegmentUsefulDataLength))
' Add the padding characters
If includePadding Then
Dim sf As StringFunctions
sf.Initialize
RetVal = RetVal & sf.Replicate(cBase32Pad, 8 - LastSegmentUsefulDataLength)
End If
Return RetVal
End Sub
Sub base32decode(data As String) As Byte()
Dim RetVal As List
Dim Segments As List
RetVal.Initialize
Segments.Initialize
' Remove any trailing padding
data = data.Replace(cBase32Pad,"")
' Process the string 8 characters at a time
Dim Index As Int = 0
Do While Index < data.Length
Dim CurrentSegment As Long = 0
Dim SegmentSize As Int = 0
Do While Index < data.Length And SegmentSize < 8
CurrentSegment = jo.RunMethod("BitRotI",Array(CurrentSegment,5)) 'Rotamos 5 bits a la izquierda
Dim l As Long = cBase32Alphabet.IndexOf(data.CharAt(Index))
CurrentSegment = jo.RunMethod("BitOr",Array(CurrentSegment,l))
Index = Index + 1
SegmentSize = SegmentSize + 1
Loop
' If the size of the last segment was less than 40 bits, pad it
CurrentSegment = jo.RunMethod("BitRotI",Array(CurrentSegment,(5 * (8 - SegmentSize))))
Segments.Add(CurrentSegment)
Loop
' Break the 5 byte segments back down into individual bytes
For Each CurrentSegment As Long In Segments
For x = 0 To 4
Dim i As Long = jo.RunMethod("BitRotD",Array(CurrentSegment,(4 - x) * 8))
Dim l As Long = 0xFF
RetVal.Add(jo.RunMethod("BitAnd",Array(i, l)))
Next
Next
' Remove any bytes of padding from the output
Dim BytesToKeep As Int = Utiles_VB.CInt(Floor(Utiles_VB.CDbl(data.Length) * 5 / 8))
Dim BytesToRemove As Int = RetVal.size - BytesToKeep
'RetVal.RemoveRange(RetVal.Count - BytesToRemove, BytesToRemove)
Do While BytesToRemove > 0
RetVal.RemoveAt(RetVal.Size - 1)
BytesToRemove = BytesToRemove - 1
Loop
Dim result(RetVal.Size) As Byte
For n = 0 To RetVal.Size - 1
result(n) = RetVal.Get(n)
Next
Return result
End Sub
#if JAVA
public Long BitOr(Long p1, Long p2){
return p1 | p2;
}
public Long BitAnd(Long p1, Long p2){
return (p1 & p2);
}
public Long BitRotD(Long num, Integer posiciones){
return (num >> posiciones);
}
public Long BitRotI(Long num, Integer posiciones){
return (num << posiciones);
}
#End If