[Gambas-user] perl unpack
Caveat
Gambas at ...1950...
Tue Sep 20 00:45:24 CEST 2011
Don't stress too much over the `, it's just a kind of non-standard
padding character. The % at the beginning of the string says we only
have 5 characters to decode so we shouldn't worry...we SHOULD always
have an exact multiple of 4 characters after the first length byte...
but some of them may not matter...
This should do it:
======================================================================
Private Function decodeUU(codedStr As String) As Byte[]
Dim idx, idy, ptr As Integer
Dim result As Byte[]
Dim lengthUU, ascAChar, ascMin32 As Integer
Dim binFour As String = ""
' First character's ascii code - 32 is the length
ascAChar = Asc(Left$(codedStr, 1))
ascMin32 = ascAChar - 32
lengthUU = ascMin32
Print "Expecting a length of: " & lengthUU
' Set the size of the result array
result = New Byte[lengthUU]
' Initialise pointer into the result array
ptr = 0
' Step through the uuencoded string character by character starting at
the 2nd character (1st is the length)
For idx = 2 To Len(codedStr)
ascAChar = Asc(Mid$(codedStr, idx, 1))
' Only include what is not whitespace
If ascAChar > 31 And ascAChar < 97 Then
' Subtract 32 from the ascii code of the character
ascMin32 = ascAChar - 32
' Assemble a block of four 6-bit values
binFour = binFour & Right$("000000" & intToBase(ascMin32,
BASE_BINARY), 6)
' Once we have 4 binary 6-bit 'characters' in our string
If Len(binFour) = 24 Then
' Treat the 4 6-bit characters as 3 8-bit characters
For idy = 1 To 3
' Make sure we don't go trying to convert more than the length
says we have to
If ptr < result.Length
Print "Bin to convert: " & Mid$(binFour, 1 + ((idy - 1) *
8), 8)
' Converts each block of 8 bits to its decimal value and
assigns to the output byte array
result[ptr] = toInt(Mid$(binFour, 1 + ((idy - 1) * 8), 8),
BASE_BINARY)
Inc ptr
End If
Next
' Be sure to clear out binFour for the next unit of UUencoding
binFour = ""
End If
End If
Next
Return result
End
======================================================================
You probably need the routines to convert between bases too:
======================================================================
Private Function convertBase(numberIn As String, fromBase As Integer,
toBase As Integer) As String
Dim value As Integer
value = toInt(numberIn, fromBase)
Return intToBase(value, toBase)
End
Private Function intToBase(numberIn As Integer, base As Integer) As
String
Dim remain, numToDivide As Integer
Dim result As String = ""
numToDivide = numberIn
Do While numToDivide / base > 0
remain = numToDivide Mod base
numToDivide = (Int)(numToDivide / base)
result = DIGITS[remain] & result
Loop
Return result
End
Private Function toInt(inputStr As String, base As Integer) As Integer
Dim idx, mult, result, value As Integer
mult = 1
For idx = Len(inputStr) To 1 Step -1
' If we're in a base with digits bigger than 9
' we need the Find to return 10 for A, 11 for B, 12 for C etc.
value = DIGITS.Find(UCase(Mid$(inputStr, idx, 1))) * mult
result = result + value
mult = mult * base
Next
Return result
End
======================================================================
And don't forget a few Consts for convenience:
======================================================================
Private Const TEST_STR As String = "%<V5N9#H`"
Private Const BASE_BINARY As Integer = 2
Private Const BASE_OCTAL As Integer = 8
Private Const BASE_DENARY As Integer = 10
Private Const BASE_HEX As Integer = 16
Private DIGITS As 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"]
======================================================================
Oh and just for fun, here's an encode function too... you will notice
that I encode "send:" CORRECTLY... LOL!
======================================================================
Private Function encodeUU(source As Byte[]) As String
Dim idx, idy, idxThree As Integer
Dim result As String
Dim aByte As Byte
Dim aBinChar, binCharGroup As String
Dim threeChars As Byte[]
binCharGroup = ""
result = result & Chr$(source.Count + 32)
For idx = 0 To source.Max
aByte = source[idx]
' Convert the byte to exactly 8 digits of binary
' so for e.g. pad 1 to become 00000001
aBinChar = Right$("00000000" & intToBase(aByte, BASE_BINARY), 8)
Print "aByte: " & aByte & " abinChar: " & aBinChar
' Add bytes together to make blocks of 3 8-bit characters
binCharGroup = binCharGroup & aBinChar
' Pad if we're at the end of the string and don't have a full 3-char
block
If idx = source.Max Then
binCharGroup = Left$(binCharGroup & "000000000000000000000000",
24)
Endif
If Len(binCharGroup) = 24 Then
Print binCharGroup
' Now treat the 3 blocks of 8 bits like 4 blocks of 6 bits....
For idy = 1 To 4
Print "char: " & idy & " has value: " & (toInt(Mid
$(binCharGroup, 1 + ((idy - 1) * 6), 6), BASE_BINARY) + 32)
' Append the Chr$ of the value of the 6-bit byte + 32 to our
result
result = result & Chr$(toInt(Mid$(binCharGroup, 1 + ((idy - 1) *
6), 6), BASE_BINARY) + 32)
Next
binCharGroup = ""
Endif
Next
Return result
End
======================================================================
Kind regards,
Caveat
On Mon, 2011-09-19 at 13:24 +0200, Ron wrote:
> I'm trying to decode this with gambas, no luck, anyone has an idea?
>
> #!/usr/bin/perl
> print pack('u', "send:");
>
> %<V5N9#H`
>
> So decoding %<V5N9#H` should result in 'send:'
>
> The pack 'u' function does uuencoding but all vb alike code doesn't
> reproduce the correct result, or struggles with the `...
>
>
> Thanks in advance!!
>
> Regards,
> Ron_2nd.
>
> ------------------------------------------------------------------------------
> BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
> Learn about the latest advances in developing for the
> BlackBerry® mobile platform with sessions, labs & more.
> See new tools and technologies. Register for BlackBerry® DevCon today!
> http://p.sf.net/sfu/rim-devcon-copy1
> _______________________________________________
> Gambas-user mailing list
> Gambas-user at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gambas-user
More information about the User
mailing list