Base64 to PDF

Base64 to PDF

Postby mtajkov » Tue Nov 15, 2022 12:18 pm

I use:

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

wherein cTxt:
Code: Select all  Expand view  RUN
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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) ]
mtajkov
 
Posts: 130
Joined: Sun Mar 08, 2009 4:33 pm

Re: Base64 to PDF

Postby cnavarro » Tue Nov 15, 2022 3:13 pm

This run Ok for me

Code: Select all  Expand view  RUN


#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
User avatar
cnavarro
 
Posts: 6549
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Base64 to PDF

Postby mtajkov » Tue Nov 15, 2022 4: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) ]
mtajkov
 
Posts: 130
Joined: Sun Mar 08, 2009 4:33 pm

Re: Base64 to PDF

Postby Antonio Linares » Tue Nov 15, 2022 4: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42120
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Base64 to PDF

Postby mtajkov » Tue Nov 15, 2022 6:00 pm

This is my code:

Code: Select all  Expand view  RUN
Function test()

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

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

      cPdf = HB_BASE64DECODE( cTxt )

   return
 


cPdf:
Code: Select all  Expand view  RUN
%PDF-1.5
2 0 obj
<< /Filter /FlateDecode /Length 16237 /Length1 28140 >>
stream
xíĽ  <UÝŰ7~$)C©ˆ&ť˘(9śůˆh2‡(S†Ę)¤LE4Q!‰Je*’Ę”ĚCEH†&c2()â˝Ö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ö)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) ]
mtajkov
 
Posts: 130
Joined: Sun Mar 08, 2009 4:33 pm

Re: Base64 to PDF

Postby Antonio Linares » Tue Nov 15, 2022 6:43 pm

This is working fine using Harbour and fails using xHarbour:
Code: Select all  Expand view  RUN
#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
User avatar
Antonio Linares
Site Admin
 
Posts: 42120
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Base64 to PDF

Postby mtajkov » Tue Nov 15, 2022 7: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) ]
mtajkov
 
Posts: 130
Joined: Sun Mar 08, 2009 4:33 pm

Re: Base64 to PDF

Postby Antonio Linares » Tue Nov 15, 2022 8: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42120
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Base64 to PDF

Postby mtajkov » Wed Nov 16, 2022 6:29 am

Thank you Antonio...

I found it on the forum, it works great:

viewtopic.php?f=3&t=34757&start=0#p206651
Best regards
Milos

[ FWH 21.11 ] [ xHarbour 1.2.3 Intl. (SimpLex) (Build 20150603) ]
mtajkov
 
Posts: 130
Joined: Sun Mar 08, 2009 4:33 pm

Re: Base64 to PDF

Postby Antonio Linares » Wed Nov 16, 2022 7:28 am

very good!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42120
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Base64 to PDF

Postby Enrico Maria Giordano » 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: Select all  Expand view  RUN
MEMOWRIT( cFile, cString, .F. )


to not add the EOF character.
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Base64 to PDF

Postby Antonio Linares » Wed Nov 16, 2022 11:23 am

Many thanks Enrico! :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42120
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Base64 to PDF

Postby cnavarro » 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
User avatar
cnavarro
 
Posts: 6549
Joined: Wed Feb 15, 2012 8:25 pm
Location: España


Re: Base64 to PDF

Postby nageswaragunupudi » Wed Nov 16, 2022 6:58 pm

Long time back, I was using my own functions
Code: Select all  Expand view  RUN
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: Select all  Expand view  RUN
/*
*
*  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
User avatar
nageswaragunupudi
 
Posts: 10646
Joined: Sun Nov 19, 2006 5:22 am
Location: India


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 50 guests