base64 decode

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
thrive4
Posts: 70
Joined: Jun 25, 2021 15:32

base64 decode

Post by thrive4 »

Well this has popped up a number of times here's a recent one:
viewtopic.php?f=8&t=29751&p=287273&hilit=base64#p287273

Never the less this version only decodes, inspired by:
https://rosettacode.org/wiki/Base64_dec ... #FreeBASIC
(there is also a encoder on rosetta for freebasic)

This code adds some rudimentary command line handling
and can be used for, by example, an image example header .b64
------=_NextPart_000_0000_6D8C1DB5.8458DF88
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Location: file:

<encoded data in base64>

Compiled with FreeBASIC-1.08.0-gcc-9.3

Code: Select all

' from https://rosettacode.org/wiki/Base64_decode_data#FreeBASIC
' added some basic file io for images 2021 thrive4
' is best to use regex to validate base64 encoding how ever not implemented here
' see https://stackoverflow.com/questions/6309379/how-to-check-for-a-valid-base64-encoded-string
'  @"^[a-zA-Z0-9\+/]*={0,3}$"
' usage commandline example base64_tut.exe <filename>.b64
' output <filename>.jpg

' setup image or file input
dim filename as string = command(1)
dim image as string
dim itemnr as integer = 1
dim listitem as string

if instr(command(1), ".") <> 0 then
    image = left(command(1), instrrev(command(1), ".") - 1) + ".jpg"
end if

Dim Shared As String B64
B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & _
"abcdefghijklmnopqrstuvwxyz" & _
"0123456789+/"

Function MIMEDecode(s As String ) As Integer
    If Len(s) Then
        MIMEdecode = Instr(B64,s) - 1
    Else
        MIMEdecode = -1
    End If
End Function

Function Decode64(s As String) As String
    Dim As Integer w1, w2, w3, w4
    Dim As String  mD
    For n As Integer = 1 To Len(s) Step 4
        w1 = MIMEdecode(Mid(s,n+0,1))
        w2 = MIMEdecode(Mid(s,n+1,1))
        w3 = MIMEdecode(Mid(s,n+2,1))
        w4 = MIMEdecode(Mid(s,n+3,1))
        If w2 >-1 Then mD+= Chr(((w1* 4 + Int(w2/16)) And 255))
        If w3 >-1 Then mD+= Chr(((w2*16 + Int(w3/ 4)) And 255))
        If w4 >-1 Then mD+= Chr(((w3*64 + w4        ) And 255))
    Next n
    Return mD
End Function

Dim As String msg64 = "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVw" & _
"IHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g="

' decode a base64 encoded file
if filename <> "" then
    msg64 = ""
    Open filename For input As 1
    Open image For output As 2
    Do Until EOF(1)
        Line Input #1, listitem
        ' ghetto validation base64
        select case true
            case instr(listitem, " ") > 0
                'nop
            case instr(listitem, "-") > 0
                'nop
            case instr(listitem, ":") > 0
                'nop
            case instr(listitem, "%") > 0
                'nop
            case len(listitem) = 0
                'nop
            case else
                msg64 = msg64 + listitem
        end select
        itemnr += 1
    Loop
    Print #2, Decode64(msg64)
    close
    end
end if    

Print msg64
Print: Print(Decode64(msg64))
sleep 3000

' output test string
'VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g=
'To err is human, but to really foul things up you need a computer.
'    -- Paul R. Ehrlich

end
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: base64 decode

Post by dodicat »

Base64 encode/decode are built into windows.

Code: Select all

Declare Function CryptBinaryToString Lib "Crypt32"Alias "CryptBinaryToStringA"(As zstring Ptr,As Long,As Long,As zstring Ptr,As Long Ptr) As Long

Declare Function CryptStringToBinary Lib "Crypt32"Alias "CryptStringToBinaryA"(As zstring Ptr,As Long,As Long,As Byte Ptr,As Long Ptr,As Long,As Long Ptr) As Long


 Function Base64Decode(s As String) As string 
    Dim As Long  Length = Len(s)
    static As ubyte b()
    redim b(length)
    CryptStringToBinary( (s),Length,1,@b(0),@Length,0, 0)
    dim as string result=string(length,0)
    for n as long=0 to length
        result[n]=b(n)
        next
    Function=result
End Function   

Function Base64Encode(p As String ) As string
    Dim As Long L=Len(p)*2,lp=len(p)
    static As ubyte  s()
    redim s(L)
   CryptBinaryToString(Strptr(p),Lp,1,@s(0),@L)
    dim as string st=string(L,0)
   for n as long=0 to L
       st[n]=s(n)
       next
    Function=st
End Function


var s="VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g="
print s
s= base64decode(s)
print s
s= base64encode(s)
print s
print base64decode(s)


sleep

 
It saves a little bit of work in Win.
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

Re: base64 decode

Post by Julcar »

These are the functions I wrote for IguanaCMS

Code: Select all

FUNCTION Base64Encode(RawData AS STRING) AS STRING
  DIM AS UBYTE Index, Char
  DIM AS STRING Chunk, Result
  'Split RawData into 3-char chunks
  FOR i AS ULONG = 1 TO LEN(RawData) STEP 3
    'Convert the 3-char chunk into 24-len binary string
    Chunk = RIGHT("00000000" + STR(BIN(ASC(MID(RawData, i, 1)))), 8) + _
            RIGHT("00000000" + STR(BIN(ASC(MID(RawData, i + 1, 1)))), 8) + _
            RIGHT("00000000" + STR(BIN(ASC(MID(RawData, i + 2, 1)))), 8)
    'Split every 24-len chunk into 4 groups of 6 binary digits
    FOR j AS UBYTE = 1 TO LEN(Chunk) STEP 6
      'Convert the 6 binary digits into an integer index
      Index = VALINT("&B" + MID(Chunk, j, 6))
      SELECT CASE Index
        CASE 0 TO 25 'A-Z
          Char = Index + 65
        CASE 26 TO 51 'a-z
          Char = Index + 71
        CASE 52 TO 61 '0-9
          Char = Index - 4
        CASE 62 '+
          Char = 43
        CASE 63 '/
          Char = 47
      END SELECT
      Result += CHR(Char)
    NEXT j
  NEXT i
  'Append equal signs to complete 3 octets at the end
  SELECT CASE LEN(RawData) MOD 3
    CASE 1
      Result = LEFT(Result, LEN(Result) - 2) + "=="
    CASE 2
      Result = LEFT(Result, LEN(Result) - 1) + "="
  END SELECT
  Base64Encode = Result
END FUNCTION

FUNCTION Base64Decode(EncodedStr AS STRING) AS STRING
  DIM AS STRING Chunk, Result
  DIM AS UBYTE Char, Index
  DIM AS ULONG NewChar
#IF 0
  'String length must be multiple of four
  IF LEN(EncodedStr) MOD 4 THEN
    Base64Decode = ""
    EXIT FUNCTION
  END IF
#ENDIF
  FOR i AS ULONG = 1 TO LEN(EncodedStr)
    Index = 0
    Char = ASC(MID(EncodedStr, i, 1))
    SELECT CASE Char
      CASE 65 TO 90
        Index = Char - 65
      CASE 97 TO 122
        Index = Char - 71
      CASE 48 TO 57
        Index = Char + 4
      CASE 43
        Index = 62
      CASE 47
        Index = 63
      CASE 10, 13
        i += 1
    END SELECT
    Chunk += RIGHT("000000" + STR(BIN(Index)), 6)
    IF i MOD 4 = 0 THEN
      FOR j AS UBYTE = 1 TO LEN(Chunk) STEP 8
        NewChar = VALINT("&B" + MID(Chunk, j, 8))
        IF NewChar > 0 THEN
          Result += CHR(NewChar)
        END IF
      NEXT j
      Chunk = ""
    END IF
  NEXT i
  Base64Decode = Result
END FUNCTION

Post Reply