Code archives/Algorithms/Base64 Encoding
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| If you don't know what Base64 is, chances are you don't need it. If you do, chances are you already know how to use it. However, I didn't know what it was or how to use it, but someone asked so I wrote the bloody thing up anyways. Defiance, you'd better wake the heck up and check this. For a quick example: SuperStrict
Repeat
Local in$ = Input( "Encode> " )
If in.ToLower( ) = "q" Then Exit
Local a@ Ptr = in.ToCString( )
Local enc$ = EncodeBase64( a, in.Length )
Print "ENCODED"
Print "<<<"+enc+">>>"
Local dec@[] = DecodeBase64( enc )
Print "DECODED"
Print "<<<"+String.FromBytes( dec, dec.Length )+">>>"
MemFree( a )
Forever | |||||
SuperStrict
Private
Const etable$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Global dtable@[256]
For Local __di:Int = 0 To etable.Length-1
dtable[etable[__di]] = __di
Next
Public
Function EncodeBase64$( in@ Ptr, sizein:Int )
If sizein <= 0 Then Return Null
Local out:Byte[64]
Local s$
Local p@ Ptr = out
Local cc% = 0
For Local i% = 0 To sizein-1 Step 3
Local c1@, c2@
c1 = in[i]&$FF
c2 = in[i+1]&$FF
p[0] = etable[in[0] Shr 2]
If i+1 < sizein Then
p[1] = etable[((in[0] & $3) Shl 4) | ((in[1] & $F0) Shr 4)]
If i+2 < sizein Then
p[2] = etable[((in[1] & $F) Shl 2) | ((in[2] & $C0) Shr 6)]
p[3] = etable[in[2] & $3F]
ElseIf i+1 < sizein Then
p[2] = etable[((in[1] & $F) Shl 2)]
EndIf
Else
p[1] = etable[((in[0] & $3) Shl 4)]
EndIf
in :+ 3
p :+ 4
cc :+ 4
If cc = 64 Then
s :+ String.FromBytes(out,cc)
p = out
cc = 0
EndIf
Next
Select sizein Mod 3
Case 0
s :+ String.FromBytes(out, cc)
Case 1
s :+ String.FromBytes(out, cc-2)+"=="
Case 2
s :+ String.FromBytes(out, cc-1)+"="
End Select
Return s
End Function
' Assumes you're passing a valid string to it
Function DecodeBase64:Byte[]( in$ )
Local f% = in.Find("=")
in = in.Replace("=","~0")
Local rm% = 0
If f = -1 Then
rm = 0
f = in.Length-1
ElseIf f = in.Length-1 Then
rm = 1
ElseIf f = in.Length-2 Then
rm = 2
EndIf
Local out@[((in.Length/4)*3)-rm]
Local p@ Ptr = out
Local bc% = 0
For Local cc:Int = 0 To f Step 4
p[0] = (dtable[in[cc]] Shl 2) | (dtable[in[cc+1]] Shr 4)
If out.Length > (bc+1) Then p[1] = ((dtable[in[cc+1]] & $F) Shl 4) | ((dtable[in[cc+2]]&$3C) Shr 2)
If out.Length > (bc+2) Then p[2] = ((dtable[in[cc+2]] & $3) Shl 6) | dtable[in[cc+3]]
bc :+ 3
p :+ 3
Next
Return out
End Function |
Comments
| ||
Good job. you might also want to try a base 128 encoder, this is one that i made for blitz to include resources in the source (its also not really been tested on many computers):
Function base128(filename$,dest$)
basekey$=" !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}©ÀÁÂÃÄÅÈÉÊËÒÓÖÙÚàáâãäåèéëñòóôõöùúüýÿ"
bitsleft=24
bitline%=0
size=FileSize(filename)-1
in=ReadFile(filename)
out=WriteFile(dest)
outline=0
WriteInt out,1635017028
WriteByte out,32
WriteByte out,34
For i=0 To size
bitline=bitline Or (ReadByte(in) Shl bitsleft)
bitsleft=bitsleft-8
While(bitsleft<18)
WriteByte out,Asc(Mid(basekey,((bitline Shr 31) And 1)*64+((bitline Shr 30) And 1)*32+((bitline Shr 29) And 1)*16+((bitline Shr 28) And 1)*8+((bitline Shr 27) And 1)*4+((bitline Shr 26) And 1)*2+((bitline Shr 25) And 1)+1,1))
outline=outline+1
If (outline=128)
outline=0
WriteByte out,34
WriteByte out,13
WriteByte out,10
WriteInt out,1635017028
WriteByte out,32
WriteByte out,34
EndIf
bitsleft=bitsleft+7
bitline=bitline Shl 7
Wend
Next
If (bitsleft<>24)
WriteByte out,Asc(Mid(basekey,((bitline Shr 31) And 1)*64+((bitline Shr 30) And 1)*32+((bitline Shr 29) And 1)*16+((bitline Shr 28) And 1)*8+((bitline Shr 27) And 1)*4+((bitline Shr 26) And 1)*2+((bitline Shr 25) And 1)+1,1))
outline=outline+1
If (outline=128)
outline=0
WriteByte out,34
WriteByte out,13
WriteByte out,10
WriteInt out,1635017028
WriteByte out,32
WriteByte out,34
EndIf
EndIf
WriteByte out,32
WriteByte out,34
CloseFile(in)
CloseFile(out)
End Function
Dim base128dekey(0)
Function debase128(dest$)
Dim base128dekey(256)
basekey$=" !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}©ÀÁÂÃÄÅÈÉÊËÒÓÖÙÚàáâãäåèéëñòóôõöùúüýÿ"
For i=0 To 127
base128dekey(Asc(Mid(basekey,i+1,1)))=i Shl 1
Next
bitsleft=24
bitline%=0
out=WriteFile(dest)
lin$=""
For i=0 To 127
lin=lin+"a"
Next
While (Len(lin)=128)
Read lin
For i=0 To Len(lin)-1
bitline=bitline Or (base128dekey(Asc(Mid(lin,i+1,1))) Shl bitsleft)
bitsleft=bitsleft-7
While(bitsleft<17)
WriteByte out,((bitline Shr 31) And 1)*128+((bitline Shr 30) And 1)*64+((bitline Shr 29) And 1)*32+((bitline Shr 28) And 1)*16+((bitline Shr 27) And 1)*8+((bitline Shr 26) And 1)*4+((bitline Shr 25) And 1)*2+((bitline Shr 24) And 1)
bitsleft=bitsleft+8
bitline=bitline Shl 8
Wend
Next
Wend
CloseFile(out)
Dim base128dekey(0)
End Function
|
| ||
| *wakes up* Nice work noel. Ive been breaking my head over this for a while while writing up my XML lib. - regards, Defiance |
| ||
The EncodeBase64() function crashes sometimes with an unnamed MAV (even in Debugmode) in the line:c1 = in[i]&$FF This is really weird. The crash occured on different i values, even with the same data provided. Is there a known problem when using Pixmap.PixelPtr(0,0)? (that's the data I want to encode). The size and anything else seems to be ok as it runs most of the time. But approx. every 6. or 7. run the code fails. Very strange... |
Code Archives Forum