NAME: Base64
CREATOR: The MIME group
PB AUTHOR: Semen Matusovski
DESCRIPTION: Base64 is related to UUencoding in that it uses the same mechanism of distributing the bits in 3 bytes into 4 bytes, but it uses a different table to map the resulting data into printable characters.
NOTES: Base64 encoded data takes one-third more space than the data before the conversion.
VARIANTS: PowerBASIC Inc. Shannon D Larratt James Moneypenny Scott Slater
SOURCE: http://www.powerbasic.com/support/forums/Forum7/HTML/001044.html
Viewing source from base64.bas   5826 bytes   Last modified Wed, 20 September 2006

   ' OutBuf is not necessary to allocate
   ' $CRLF after each nGroups per 3 input bytes

   Function Encode_BASE64(InBuf As String, ByVal nGroups As Long, OutBuf As String) As Long
      #Register None

      OutBuf = Space$(4 * Fix((Len(InBuf) + 2) / 3) + 2 * Fix(Len(InBuf) / (3 * nGroups)))

      ! PUSH EBX

      ! LEA EBX, Encode_BASE64_Trt

      ! MOV EDI, OutBuf
      ! MOV EDI, [EDI]                    ' StrPtr(OutBuf)

      ! MOV ESI, InBuf
      ! MOV ESI, [ESI]                    ' StrPtr(InBuf)

      ! MOV EDX, ESI
      ! SUB EDX, 4
      ! MOV EDX, [EDX]                    ' Len(InBuf)

      ! MOV ECX, nGroups

 Encode_BASE64_Lb1:
      ! CMP EDX, 0
      ! JLE Encode_BASE64_Lb4

      ! MOV AL, [ESI]
      ! SHR AL, 2
      ! XLATB
      ! MOV [EDI], AL
      ! INC EDI

      ! MOV AL, [ESI + 1]
      ! MOV AH, [ESI]
      ! SHR AX, 4
      ! AND AL, &H3F
      ! XLATB
      ! MOV [EDI], AL
      ! INC EDI

      ! CMP EDX, 1
      ! JNE Encode_BASE64_Lb2

      ! MOV AL, 61                        ' Add ==
      ! MOV [EDI], AL
      ! INC EDI
      ! MOV [EDI], AL
      ! INC EDI
      ! JMP Encode_BASE64_Lb4

 Encode_BASE64_Lb2:
      ! MOV AL, [ESI + 2]
      ! MOV AH, [ESI + 1]
      ! SHR AX, 6
      ! AND AL, &H3F
      ! XLATB
      ! MOV [EDI], AL
      ! INC EDI

      ! CMP EDX, 2
      ! JNE Encode_BASE64_Lb3

      ! MOV AL, 61                        ' Add =
      ! MOV [EDI], AL
      ! INC EDI
      ! JMP Encode_BASE64_Lb4

 Encode_BASE64_Lb3:
      ! MOV AL, [ESI + 2]
      ! AND AL, &H3F
      ! XLATB
      ! MOV [EDI], AL
      ! INC EDI

      ! ADD ESI, 3
      ! SUB EDX, 3

      ! DEC ECX
      ! CMP ECX, 0
      ! JNE Encode_BASE64_Lb1

      ! MOV AL, 13                         ' Add $CRLF
      ! MOV [EDI], AL
      ! MOV AL, 10
      ! MOV [EDI + 1], AL
      ! ADD EDI, 2
      ! MOV ECX, nGroups
      ! JMP Encode_BASE64_Lb1

 Encode_BASE64_Lb4:
      ! POP EBX

      Exit Function

 Encode_Base64_Trt:
      ! DB 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
87, 88, 89, 90
      ! DB 97, 98,
99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122
      ! DB 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
   End Function

   ' OutBuf is not necessary to allocate
   ' Function = offset in InBuf for last not recognized character
   Function Decode_Base64(ByVal InBuf As Dword, OutBuf As String) As Long
      #Register None
      Dim i As Long

      ! MOV EDI, 0
      ! MOV AH, 0

 Decode_BASE64_Lb1:
      ! PUSH EBX
      ! LEA EBX, i
      ! MOV ESI, InBuf
      ! PUSH ESI
      ! MOV CL, 0

 Decode_BASE64_Lb2:
      ! MOV AL, [ESI]

      ! CMP AL, 13                         ' Pass $CRLF
      ! JE Decode_BASE64_Lb15
      ! CMP AL, 10
      ! JE Decode_BASE64_Lb15

      ! CMP AL, 65                         ' A .. Z
      ! JL Decode_BASE64_Lb3
      ! CMP AL, 90
      ! JG Decode_BASE64_Lb3
      ! SUB AL, 65
      ! JMP Decode_BASE64_Lb8

 Decode_BASE64_Lb3:
      ! CMP AL, 97                         ' a .. z
      ! JL Decode_BASE64_Lb4
      ! CMP AL, 122
      ! JG Decode_BASE64_Lb4
      ! SUB AL, 71
      ! JMP Decode_BASE64_Lb8

 Decode_BASE64_Lb4:
      ! CMP AL, 48                         ' 0 .. 9
      ! JL Decode_BASE64_Lb5
      ! CMP AL, 57
      ! JG Decode_BASE64_Lb5
      ! ADD AL, 4
      ! JMP Decode_BASE64_Lb8

 Decode_BASE64_Lb5:
      ! CMP AL, 43                         ' +
      ! JNE Decode_BASE64_Lb6
      ! MOV AL, 62
      ! JMP Decode_BASE64_Lb8

 Decode_BASE64_Lb6:
      ! CMP AL, 47                         ' /
      ! JNE Decode_BASE64_Lb7
      ! MOV AL, 63
      ! JMP Decode_BASE64_Lb8

 Decode_BASE64_Lb7:
      ! CMP AL, 61                         ' =
      ! JNE Decode_BASE64_Lb18
      ! MOV AL, 255

 Decode_BASE64_Lb8:
      ! INC CL
      ! CMP CL, 1
      ! JNE Decode_BASE64_Lb9
      ! MOV [EBX], AL
      ! JMP Decode_BASE64_Lb15

 Decode_BASE64_Lb9:
      ! CMP CL, 2
      ! JNE Decode_BASE64_Lb10
      ! MOV [EBX + 1], AL
      ! JMP Decode_BASE64_Lb15

 Decode_BASE64_Lb10:
      ! CMP CL, 3
      ! JNE Decode_BASE64_Lb11
      ! MOV [EBX + 2], AL
      ! JMP Decode_BASE64_Lb15

 Decode_BASE64_Lb11:
      ! MOV [EBX + 3], AL

      ! MOV CL, [EBX]
      ! SHL CL, 2
      ! MOV CH, [EBX + 1]
      ! SHR CH, 4
      ! OR  CL, CH

      ! CMP AH, 0
      ! JE Decode_BASE64_Lb12
      ! MOV [EDI], CL

 Decode_BASE64_Lb12:
      ! MOV CL, [EBX + 2]
      ! CMP CL, 255
      ! JE  Decode_BASE64_Lb17

      ! MOV CL, [EBX + 1]
      ! SHL CL, 4
      ! MOV CH, [EBX + 2]
      ! SHR CH, 2
      ! OR  CL, CH

      ! CMP AH, 0
      ! JE Decode_BASE64_Lb13
      ! MOV [EDI + 1], CL

 Decode_BASE64_Lb13:
      ! MOV CL, [EBX + 3]
      ! CMP CL, 255
      ! JE  Decode_BASE64_Lb16

      ! MOV CL, [EBX + 2]
      ! SHL CL, 6
      ! MOV CH, [EBX + 3]
      ! OR  CL, CH

      ! CMP AH, 0
      ! JE Decode_BASE64_Lb14
      ! MOV [EDI + 2], CL

 Decode_BASE64_Lb14:
      ! ADD EDI, 3
      ! MOV CL, 0

 Decode_BASE64_Lb15:
      ! INC ESI
      ! JMP Decode_BASE64_Lb2
 Decode_BASE64_Lb16:
      ! INC EDI

 Decode_BASE64_Lb17:
      ! INC EDI

 Decode_BASE64_Lb18:
      ! MOV ECX, ESI
      ! POP ESI
      ! SUB ECX, ESI
      ! MOV Function, ECX
      ! POP EBX

      ! CMP AH, 0
      ! JNE Decode_BASE64_Lb19
      ! MOV AH, 1

      ! MOV i, EDI

      OutBuf = Space$(i)
      ! MOV EDI, OutBuf
      ! MOV EDI, [EDI]
      ! JMP Decode_BASE64_Lb1

 Decode_BASE64_Lb19:
      Exit Function
   End Function

Back to The Archives