FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Base64 to PDF
Posts: 130
Joined: Sun Mar 08, 2009 04:33 PM
Base64 to PDF
Posted: Tue Nov 15, 2022 12:18 PM
I use:

cPdf = HB_BASE64DECODE( cTxt )
MEMOWRIT( "Test.Pdf", cPdf, .F. )

wherein cTxt:
Code (fw): Select all Collapse
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NCBbNTAwXSA4MSBbNTU2XSA4MiBbNTU2XSAyMjggWzYxMV0gMjQgWzU1Nl0gNzMgWzI3OF0gODAgWzgzM10gMTcgWzI3OF0gODYgWzUwMF0gNTQgWzY2N10gMjI5IFs1MDBdIDU3IFs2NDldIDc4IFs1MDBdIDI1MiBbNTAwXSA4MyBbNTU2XSA3NCBbNTU2XSAzNSBbMTAxNV0gNzAgWzUwMF0gNTYgWzcyMl0gOCBbODg5XSA5MyBbNTAwXSAxNiBbMzMzXSA0NSBbNTAwXSAzOCBbNzIyXSAyMjcgWzUwMF0gNjEgWzYxMV0gMjI2IFs2NjddIDQ5IFs3MjJdIDE1IFsyNzhdIDI1NSBbNTU2XSA0MSBbNjExXSAxMSBbMzMzXSA1IFszNTVdIDE4IFsyNzhdIDEyIFszMzNdIF0NCj4+DQplbmRvYmoNCjMgMCBvYmoNCjw8DQovVHlwZSAvRm9udA0KL1N1YnR5cGUgL1R5cGUwDQovQmFzZUZvbnQgL0FyaWFsDQovRW5jb2RpbmcgL0lkZW50aXR5LUgNCi9EZXNjZW5kYW50Rm9udHMgWzkgMCBSXQ0KL1RvVW5pY29kZSA3IDAgUg0KPj4NCmVuZG9iag0KMTAgMCBvYmoNCjw8DQovVHlwZSAvRm9udERlc2NyaXB0b3INCi9Gb250TmFtZSAvQXJpYWwsQm9sZA0KL0ZvbnRGYW1pbHkgL0FyaWFsLEJvbGQNCi9GbGFncyAzMg0KL0ZvbnRCQm94IFstNjI4IC0zNzYgMjAwMCAxMDU2IF0NCi9JdGFsaWNBbmdsZSAwDQovQXNjZW50IDcyOA0KL0Rlc2NlbnQgLTIxMA0KL0xlYWRpbmcgMTE3DQovQ2FwSGVpZ2h0IDExMTcNCi9TdGVtViAxNjYNCi9BdmdXaWR0aCA0NzkNCi9NeFdpZHRoIDI2MjgNCi9NaXNzaW5nV2lkdGggNDc5DQo+Pg0KZW5kb2JqDQoxMSAwIG9iag0KPDwgL0xlbmd0aCA1NDIgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9MZW5ndGgxIDExODMgPj4NCnN0cmVhbQ0KeAFdVMuO2zAMvBvwP+i4RQ/W27tAECBxYiCHPtB0P8CxlayBxDYU55C/L0XSi7Y+BBmRQw2HkorqsDsM/SyKn3Fsj2EW537oYriPj9gGcQqXfsgzpUXXt/MCcbW9NVOeFcA/Pu9zuB2G85hnq5UofgHpPseneNl04yl8gawfsQuxHy7i5b06/rtw6MIw9/MzrR4f03QNN1gQMs/Wa9GFM7Crb830vbkFUWxi31y/bsdr91fo93MKAhSmXEUa27EL96lpQ2yGSwBZEr61WNXwrfMsDN3/Gc4R83RuP5qIDOOAIaXTwFhJqS1CqwjWuwSVrAia1wSlcwwVQrsnKA1CLQkqKmW4lKKoWaIlJhvLyRqhrhm+ITSeIYk0LBKWBWh1hqJQMkG7Y0iVHVc2tK/jfXWFle0bJWtKtksyybAsA+RgZW5fbZBrSuaSKsuqFHolzYaiylMyi1RkHdiNtiuSYViG2lLyK3FBTtrXs3WORJYs0hLXM7feJ66S3L6joXgeiiWRnkXC6FLlcoHUr+d+wcIU9dyCxsrSbkmVpo4sdwRjx2SOOmqw5LMBw0nRkm13ZE7JlR2VKpdSdWpB+sVnagG2R68kRWFyCEFOquwXr8gcv5hDMjzL0HSQLB8kOAXIXbyiaMlRmEaKgjjcSElUpTl5jwdJ4VDgbi13CP7SK/F5gdtHjHC78TEp0mq6xv0QPh+caZzwevLPHwcXCqRlbmRzdHJlYW0NCmVuZG9iag0KMTIgMCBvYmoNCjw8DQovUmVnaXN0cnkgKEFkb2JlKSAvT3JkZXJpbmcgKElkZW50aXR5KSAvU3VwcGxlbWVudCAwDQo+Pg0KZW5kb2JqDQoxMyAwIG9iag0KPDwNCi9UeXBlIC9Gb250DQovU3VidHlwZSAvQ0lERm9udFR5cGUyDQovQmFzZUZvbnQgL0FyaWFsLEJvbGQNCi9DSURTeXN0ZW1JbmZvIDEyIDAgUg0KL0ZvbnREZXNjcmlwdG9yIDEwIDAgUg0KL1cgWyA1MyBbNzIyXSAzNiBbNzIyXSAyNTMgWzcyMl0gNTYgWzcyMl0gNDkgWzcyMl0gMyBbMjc4XSAyMCBbNTU2XSAxOSBbNTU2XSAyMyBbNTU2XSAxOCBbMjc4XSAyNSBbNTU2XSAyMSBbNTU2XSA1NCBbNjY3XSA0OCBbODMzXSA1NSBbNjExXSA1MSBbNjY3XSA0NCBbMjc4XSAzOSBbNzIyXSA1MCBbNzc4XSA0NyBbNjExXSAyNiBbNTU2XSAzNyBbNzIyXSAyOSBbMzMzXSAyMiBbNTU2XSAyNCBbNTU2XSAyOCBbNTU2XSAyNyBbNTU2XSA2OCBbNTU2XSA4NyBbMzMzXSA3NiBbMjc4XSAyNTQgWzU1Nl0gODEgWzYxMV0gNjkgWzYxMV0gODUgWzM4OV0gODIgWzYxMV0gNzcgWzI3OF0gNDYgWzcyMl0gMzggWzcyMl0gNzggWzU1Nl0gODggWzYxMV0gODMgWzYxMV0gOTMgWzUwMF0gODYgWzU1Nl0gNzkgWzI3OF0gMTcgWzI3OF0gMTUgWzI3OF0gNzUgWzYxMV0gNzEgWzYxMV0gNzIgWzU1Nl0gNDEgWzYxMV0gODAgWzg4OV0gODkgWzU1Nl0gNTcgWzY2N10gMTYgWzMzM10gMjI3IFs1NTZdIF0NCj4+DQplbmRvYmoNCjQgMCBvYmoNCjw8DQovVHlwZSAvRm9udA0KL1N1YnR5cGUgL1R5cGUwDQovQmFzZUZvbnQgL0FyaWFsLEJvbGQNCi9FbmNvZGluZyAvSWRlbnRpdHktSA0KL0Rlc2NlbmRhbnRGb250cyBbMTMgMCBSXQ0KL1RvVW5pY29kZSAxMSAwIFINCj4+DQplbmRvYmoNCjEgMCBvYmoNCjw8DQovVHlwZSAvUGFnZXMNCi9LaWRzIFs1IDAgUiBdDQovQ291bnQgMQ0KPj4NCmVuZG9iag0KMTQgMCBvYmoNCjw8DQovVGl0bGUgPEZFRkYwMDVBMDA2MTAwNkMwMDY5MDA2ODAwNjU+DQovQXV0aG9yIDxGRUZGMDA0RDAwNjkwMDZDMDA2RjAxNjEwMDIwMDA1NDAwNjEwMDZBMDA2QjAwNkYwMDc2Pg0KL1N1YmplY3QgPEZFRkYwMDQ3MDA1MjAwNDEwMDUwMDA1MjAwNDUwMDRCMDAyMDAwNDQwMDRGMDA0RjAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjA+DQovS2V5d29yZHMgPEZFRkY+DQovQ3JlYXRvciA8RkVGRjAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMDAwMjAwMDIwMDAyMD4NCi9Qcm9kdWNlciA8RkVGRjAwNTMwMDZEMDA2MTAwNzIwMDc0MDA3MDAwNzIwMDY5MDA2RTAwNzQwMDIwMDA2NDAwNkYwMDZGPg0KL0NyZWF0aW9uRGF0ZSAoRDoyMDIyMTExNDE5MzEyOCkNCi9Nb2REYXRlIChEOjIwMjIxMTE0MTkzMTI4KQ0KPj4NCmVuZG9iag0KMTUgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YWxvZw0KL1BhZ2VzIDEgMCBSDQovUGFnZU1vZGUgL1VzZU5vbmUNCi9WaWV3ZXJQcmVmZXJlbmNlcyA8PA0KL0Rpc3BsYXlEb2NUaXRsZSB0cnVlDQovUHJpbnRTY2FsaW5nIC9Ob25lDQo+Pg0KPj4NCmVuZG9iag0KeHJlZg0KMCAxNg0KMDAwMDAwMDAwMCA2NTUzNSBmDQowMDAwMDIwMjUxIDAwMDAwIG4NCjAwMDAwMDAwMTAgMDAwMDAgbg0KMDAwMDAxODMzNCAwMDAwMCBuDQowMDAwMDIwMTA0IDAwMDAwIG4NCjAwMDAwMTYzNDIgMDAwMDAgbg0KMDAwMDAxNjU0NSAwMDAwMCBuDQowMDAwMDE2ODExIDAwMDAwIG4NCjAwMDAwMTc1MDUgMDAwMDAgbg0KMDAwMDAxNzU4NCAwMDAwMCBuDQowMDAwMDE4NDc0IDAwMDAwIG4NCjAwMDAwMTg3NTIgMDAwMDAgbg0KMDAwMDAxOTM4NiAwMDAwMCBuDQowMDAwMDE5NDY2IDAwMDAwIG4NCjAwMDAwMjAzMTYgMDAwMDAgbg0KMDAwMDAyMDg3NCAwMDAwMCBuDQp0cmFpbGVyDQo8PA0KL1NpemUgMTYNCi9Sb290IDE1IDAgUg0KL0luZm8gMTQgMCBSDQovSUQgWzw1Yzc0ZTE5MTI2Zjk5YjYwYTdjMjA3NGFkZGU1ODRjOT48NWM3NGUxOTEyNmY5OWI2MGE3YzIwNzRhZGRlNTg0Yzk+XQ0KPj4NCnN0YXJ0eHJlZg0KMjEwMjENCiUlRU9GDQo=
I don't get the correct pdf?

if the same cTxt I decode in https://base64.guru/converter/decode/pdf I get the correct PDF.

Best regards,
Miloš
Best regards

Milos



[ FWH 21.11 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603) ]
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 03:13 PM
This run Ok for me
Code (fw): Select all Collapse
#include "Fivewin.ch"

Function Main()

   local cTxt := hb_MemoRead( "decode64.txt" )
   local cPdf := HB_BASE64DECODE( cTxt )
   hb_MEMOWRIT( "Test.Pdf", cPdf, .F. )

Return nil
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 130
Joined: Sun Mar 08, 2009 04:33 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 04:25 PM

I am using xHarbour build 1.2.1, function HB_MEMOREAD() does not exist. I guess the problem might be in MEMOREAD()?

Best regards,

Miloš

Best regards

Milos



[ FWH 21.11 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603) ]
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 04:31 PM

Dear Miloš,

Yes, as memoWrit() adds an extra HB_CHAR_EOF character

Use SubStr() to remove it when reading the saved string

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 130
Joined: Sun Mar 08, 2009 04:33 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 06:00 PM
This is my code:
Code (fw): Select all Collapse
Function test()

    LOCAL cFileName := cGetFile("*.txt", "Izaberi TXT" )
    LOCAL cPdf

    cTxt=MemoRead(cFileName) //[b]I check this cTxt on https://base64.guru/converter/decode/pdf[/b]

      cPdf = HB_BASE64DECODE( cTxt )

   return
cPdf:
Code (fw): Select all Collapse
%PDF-1.5
2 0 obj
<< /Filter /FlateDecode /Length 16237 /Length1 28140 >>
stream
xíĽ  <UÝŰ7~$)C©ˆ&ť˘(9śůˆh2‡(S†Ę)¤LE4Q!‰Je*’Ę”ĚCEH†&c2”(BĹ)â˝ÖFw4ýşźçů˙ßĎóy«ÓŢ{ía}×5_×Z{;psI’2  /   é’O˘R   d:žNĄ¤hxS[nŽuĘÜşx
‰[%Ľ6ë7ă%´×ÁŢşMëńč„2ŢqŹ“94(ŕ
$6¬ßbÄ͡Ľ›cřŮđKŹŠ‚˛Ž…‡cż¸á:Üzë¤Ič++ëdřÇ6•Ťmňd6vö)Są8¸¸8989ą§Ďâáž>s:''Ďž™łyůřř¸fđ
Ěá˜ĹËÇ‹ÂÂ
÷Lf›ĆĆ6Ť—›“›÷Ż˙çâfNĹmc‰ceY‚›4“…u&ËpnŕdcÁţŕF˙°LbťĚ6…}ę4N¸ • 7‰…•uŇdV„®
I think the function HB_BASE64DECODE( cTxt ) does not give a good result?

Best Regards,
Miloš
Best regards

Milos



[ FWH 21.11 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603) ]
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 06:43 PM
This is working fine using Harbour and fails using xHarbour:
Code (fw): Select all Collapse
#include "FiveWin.ch"

function Main()

   local cPdf := memoRead( "fwintro.pdf" )
   local cText

   cText = hb_base64Encode( cPdf )  // xHarbour fails here
   MsgInfo( Len( cText ) )

   memoWrit( "encoded.txt", cText )

   cText = SubStr( memoRead( "encoded.txt" ), 1, Len( memoRead( "encoded.txt" ) ) - 1 )
   MsgInfo( Len( hb_base64Decode( cText ) ) )
   memoWrit( "fwintro2.pdf", hb_base64Decode( cText ) )

   ShellExecute( 0, "open", "fwintro2.pdf" )

return nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 130
Joined: Sun Mar 08, 2009 04:33 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 07:49 PM

Antonio,

Works with xHarbour xHarbour 1.2.3 Intl. (SimpLex) (Build 20201212) but not with xHarbour build 1.2.1 Intl. (SimplLex) (Rev. 9382). I have to use xHarbour build 1.2.1 Intl. (SimplLex) (Rev. 9382)?

Best regards

Milos



[ FWH 21.11 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603) ]
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Base64 to PDF
Posted: Tue Nov 15, 2022 08:05 PM

Dear Milos,

Then you have to compare the source code of both xHarbour builds and check the differences and implement your own modified functions

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 130
Joined: Sun Mar 08, 2009 04:33 PM
Re: Base64 to PDF
Posted: Wed Nov 16, 2022 06:29 AM
Thank you Antonio...

I found it on the forum, it works great:

https://www.fivetechsupport.com/forums/viewtopic.php?f=3&t=34757&start=0#p206651
Best regards

Milos



[ FWH 21.11 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603) ]
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Base64 to PDF
Posted: Wed Nov 16, 2022 07:28 AM

very good!

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 9022
Joined: Thu Oct 06, 2005 08:17 PM
Re: Base64 to PDF
Posted: Wed Nov 16, 2022 11:12 AM
Antonio Linares wrote:Dear Miloš,

Yes, as memoWrit() adds an extra HB_CHAR_EOF character

Use SubStr() to remove it when reading the saved string
It is not required. Just add the third parameter to MEMOWRIT():
Code (fw): Select all Collapse
MEMOWRIT( cFile, cString, .F. )
to not add the EOF character.
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Base64 to PDF
Posted: Wed Nov 16, 2022 11:23 AM
Many thanks Enrico! :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Base64 to PDF
Posted: Wed Nov 16, 2022 12:21 PM
mtajkov wrote:I use:

cPdf = HB_BASE64DECODE( cTxt )
MEMOWRIT( "Test.Pdf", cPdf, .F. )

[/code]

I don't get the correct pdf?

if the same cTxt I decode in https://base64.guru/converter/decode/pdf I get the correct PDF.

Best regards,
Miloš
look at the first post
So I think the problem has nothing to do with the MemoWrit function
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 9022
Joined: Thu Oct 06, 2005 08:17 PM
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Base64 to PDF
Posted: Wed Nov 16, 2022 06:58 PM
Long time back, I was using my own functions
Code (fw): Select all Collapse
GN_BASE64ENCODE
GN_BASE64DECODE
GN_BASE64URL
I am posting one of my old programs here.
You may check if my old functions work correctly for you.
Code (fw): Select all Collapse
/*
*
*  BASE64.prg
*  May 02-2013 01:50 PM
*
*/

#include "FiveWin.Ch"


#ifdef __XHARBOUR__
#xtranslate HB_BASE64ENCODE( <c> ) => HB_BASE64( <c>, Len( <c> ) )
#endif

#ifdef TEST

//----------------------------------------------------------------------------//

function Main()

   local oDlg, cStr, oFont, cEnc, cDec, cEncH, cDecH, oEncUrl, oDecUrl
   local oStr, oEnc, oDec, oEncH, oDecH, cEncUrl, cDecUrl

//   FW_SetUnicode( .t. )

   test()
   return nil

   cStr := cEnc := cDec := cEncH := cDecH := cEncUrl := cDecUrl := ""

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12

   DEFINE DIALOG oDlg SIZE 900,700 PIXEL TRUEPIXEL FONT oFont ;
      TITLE FWVERSION + " BASE64 and BASE64URL"

   @  20, 20 GET cStr MEMO SIZE 660,080 PIXEL OF oDlg

   @  20,700 BTNBMP PROMPT "Encode" SIZE 180,30 PIXEL OF oDlg FLAT ;
      ACTION ( cEnc  := GN_BASE64ENCODE( Trim( cStr ) ), oEnc:Refresh(), ;
               cDec  := GN_BASE64DECODE( cEnc ), oDec:Refresh(), ;
               cEncH := HB_BASE64ENCODE( Trim( cStr ) ), oEncH:Refresh(), ;
               cDecH := HB_BASE64DECODE( cEncH ), oDecH:Refresh(), ;
               cEncUrl := GN_BASE64URL( Trim( cStr ) ), ;
               cDecUrl := GN_BASE64DECODE( cEncUrl ), ;
               oDlg:Update()  )

   @ 130, 20 SAY "GNR"     SIZE 400,20 PIXEL OF oDlg CENTER
#ifdef __XHARBOUR__
   @ 130,480 SAY "xHarbour" SIZE 400,20 PIXEL OF oDlg CENTER
#else
   @ 130,480 SAY "Harbour" SIZE 400,20 PIXEL OF oDlg CENTER
#endif

   @ 150, 20 SAY "BASE64" SIZE 100,16 PIXEL OF oDlg

   @ 170, 20 GET oEnc VAR cEnc MEMO ;
      SIZE 400,100 PIXEL OF oDlg UPDATE READONLY

   @ 290, 20 GET oDec VAR cDec MEMO ;
      SIZE 400,100 PIXEL OF oDlg UPDATE READONLY

   @ 170, 480 GET oEncH VAR cEncH MEMO ;
      SIZE 400,100 PIXEL OF oDlg UPDATE READONLY

   @ 290, 480 GET oDecH VAR cDecH MEMO ;
      SIZE 400,100 PIXEL OF oDlg UPDATE READONLY

   @ 200, 430 SAY If( cEnc == cEncH, "==", "<>" ) SIZE 40,20 PIXEL CENTER OF oDlg UPDATE

   @ 320, 430 SAY If( cDec == cDecH, "==", "<>" ) SIZE 40,20 PIXEL CENTER OF oDlg UPDATE

   @ 410,  20 SAY If( cDec == Trim( cStr ), "MATCHES WITH INPUT", "DOES NOT MATCH WITH INPUT" ) ;
      SIZE 400,20 PIXEL CENTER OF oDlg UPDATE

   @ 410, 480 SAY If( cDecH == Trim( cStr ), "MATCHES WITH INPUT", "DOES NOT MATCH WITH INPUT" ) ;
      SIZE 400,20 PIXEL CENTER OF oDlg UPDATE

   @ 440, 20 SAY "GN_BASE64URL" SIZE 100,16 PIXEL OF oDlg

   @ 480,  20 GET oEncUrl VAR cEncUrl MEMO SIZE 400,100 PIXEL OF oDlg UPDATE READONLY
   @ 480, 480 GET oDecUrl VAR cDecUrl MEMO SIZE 400,100 PIXEL OF oDlg UPDATE READONLY

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return (0)

#endif

//----------------------------------------------------------------------------//

function GN_BASE64URL( cData )

   local cEnc  := GN_BASE64ENCODE( cData )

   cEnc  := StrTran( StrTran( cEnc, '+', '-' ), '/', '_' )
   cEnc  := RemRight( cEnc, '=' )

return cEnc

//----------------------------------------------------------------------------//

function GN_BASE64ENCODE( cData )

   local cRet  := ''

   do while Len( cData ) > 0 //! Empty( cData )
      cRet     += EncodeSub( Left( cData, 3 ) )
      cData    := SubStr( cData, 4 )
   enddo

return cRet

//----------------------------------------------------------------------------//

static function EncodeSub( cData )

   static cRef := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

   local cIn      := Left( cData + Chr( 0 ) + Chr( 0 ), 3 )
   local n, x, i
   local cOut     := ""

   n     := Asc( SubStr( cIn, 1, 1 ) ) * 256 * 256 + ;
            Asc( SubStr( cIn, 2, 1 ) ) * 256 + ;
            Asc( SubStr( cIn, 3, 1 ) )

   for i := 1 to 4
      x     := n % 64 + 1
      cOut  := SubStr( cRef, x, 1 ) + cOut
      n     := Int( n / 64 )
   next

   if Len( cData ) == 1
      cOut  := Left( cOut, 2 ) + "=="
   elseif Len( cData ) == 2
      cOut  := Left( cOut, 3 ) + "="
   endif

return cOut

//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//

function GN_BASE64DECODE( cIn )

   local cOut  := ""

   cIn   := StrTran( StrTran( cIn, '-', '+' ), '_', '/' )

   do while Len( cIn ) > 0 //! Empty( cIn )
      cOut  += b64_sub( Left( cIn, 4 ) )
      cIn   := SubStr( cIn, 5 )
   enddo

return cOut

//----------------------------------------------------------------------------//

static function b64_sub( c4 )

   static cRef := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

   local a,b,c,d
   local x,y,z
   local cRet

   c4 := Left( c4 + "==", 4 )
   a  := At( SubStr( c4, 1, 1 ), cRef ) - 1
   b  := At( SubStr( c4, 2, 1 ), cRef ) - 1
   c  := At( SubStr( c4, 3, 1 ), cRef ) - 1
   d  := At( SubStr( c4, 4, 1 ), cRef ) - 1

   x  := a * 4
   x  += Int( b / 16 )
   if c == -1
      return Chr( x )
   endif
   b  := b % 16
   y  := b * 16
   y  += Int( c / 4 )
   if d == -1
      return Chr( x ) + Chr( y )
   endif
   c  := c % 4
   z  := c * 64
   z  += d

return Chr( x ) + Chr( y ) + Chr( z )

//----------------------------------------------------------------------------//

func test()

   local x := { 14, 209, 33, 83, 121, 99, 108, 72, 60, 47, 127, 21, 88, 7, 212, 2, 163, 178, 40, 3, 58, 249, 124, 126, 23, 129, 154, 195, 22, 158, 166, 101}
   local y := { 197, 10, 7, 211, 140, 60, 112, 229, 216, 241, 45, 175, 8, 74, 84, 128, 166, 101, 144, 197, 242, 147, 80, 154, 143, 63, 127, 138, 131, 163, 84, 213 }

   local r  := ""
   local s  := ""

   aeval( x, { |n| r += chr(n) } )
   aeval( y, { |n| s += chr(n) } )

   ? STRTOHEX( r + s )
   ? GN_BASE64URL( r + s )

return nil
Regards



G. N. Rao.

Hyderabad, India

Continue the discussion