sponsored links



No announcement yet.

IBM Base64 API in RPG - apr_base64_decode procedure

  • Filter
  • Time
  • Show
Clear All
new posts

  • IBM Base64 API in RPG - apr_base64_decode procedure

    I am trying to use IBM supplied apr_base64_decode in RPG. But the decoded string is ending up as garabage.

    Please help me identify what I am missing. Is this due to the Arabic (420) CCSID of our IBM i machine and I need to perform proper conversion? Hoping for guidance.

    0001.00      H BNDDIR('BASE64':'QC2LE')                                  
    0001.01       /copy APR_B64_H                                            
    0001.03      D BASE64DATA      s             70A   DIM(3) CTDATA PERRCD(1)
    0003.00      d decdata         s          32764a                          
    0003.01      d decoded         s          32764a                          
    0003.02      d declen          s             10i 0                        
    0003.03      d i               s             10i 0                        
    0004.00       /free                                                      
    0004.01             // read the data in and concat it together            
    0004.02             for i = 1 to %elem(base64data);                      
    0004.03                decdata = %trimr(decdata) + base64data(i);        
    0004.04             endfor;                                              
    0004.06             // decode                                            
    0004.07             declen = apr_base64_decode(DECODED:DECDATA);          
    0004.11           *inlr = *on;                                                    
    0004.14       /end-free                                                          
    0006.00 ** BASE64DATA                                                            
    0008.00 VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cgICAgeg0KQm    
    0009.00 FhIGJhYSBibGFjayBzaGVlcCBoYXZlIHlvdSBhbnkgd29vbCAgICAgICAgICAgeg0KSmFj    
    0010.00 ayBhbmQgSmlsbCB3ZW4gdXAgdGhlIGhpbGwgICAgICAgICAgICAgICAgICAgeg0K
    The Plain Text of my base 64 data is supposedly
    The quick brown fox jumped over the lazy dog    z
    Baa baa black sheep have you any wool           z
    Jack and Jill wen up the hill                   z

    I can see that the BASE64DATA was properly composed for DECDATA variable

    EVAL DECDATA                                                          
    DECDATA =                                                            
         1   'VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cg'
        61   'ICAgeg0KQmFhIGJhYSBibGFjayBzaGVlcCBoYXZlIHlvdSBhbnkgd29vbCAg'
       121   'ICAgICAgICAgeg0KSmFjayBhbmQgSmlsbCB3ZW4gdXAgdGhlIGhpbGwgICAg'
       181   'ICAgICAgICAgICAgICAgeg0K                                    '
       241   '                                                            '
    But my DECODED is ending up as garbage


    I have tried similar code in Java using the Oracle/Sun supplied API and it is working fine (I did asked String to use UTF-8 when I instantiated it with the byte[] decoded data). It is even already reading from a CLOB field in DB2 400. Unfortunately, I have to do the work in RPG.
    Attached Files

  • #2
    I think the base64 encoded input string is expected to be ascii and the rpg program is not supplying ascii data to the apr_base64_decode procedure. Try converting the base64data to ascii before calling the apr_base64_decode procedure.


    • #3
      Is this the job of iconv api? DECDATA must be converted first into ascii?
      I wished IBM provided a working document for these procedures. I am only depending from discussion forums.


      • #4
        I backtracked for a simple test of encoding 'AA' and decoding the resulting character.
        0004.53        // encode                                                              
        0004.55        declen = apr_base64_encode(ENCODED:%trim(DECDATA):%len(DECDATA));      
        0004.56        dsply ENCODED;                                                         
        0005.03        // decode                                                              
        0005.04        declen = apr_base64_decode(DECODED:%trim(ENCODED));                    
        0005.09        dsply DECODED;
        apr_base64_encode is working OK and is producing "QUE=". Unfortunately, apr_base64_decode using the resulting value from encode, ends up with empty value. HELP please


        • #5
          The procedures require ascii.

          Maybe something like this
          d in              s          32764a   ccsid(819)  
          d out             s          32764a   ccsid(819)  
               in = 'AA';
               declen = apr_base64_encode(in:%trim(in):%len(in));
               declen = apr_base64_decode(out:%trim(in));


          • #6
            Most likely 819 wouldn't be the right CCSID for the ASCII string. 819 is for the "Latin" character set which is used for the European languages including English. It doesn't include the Arabic characters. From this page, it looks like 864 would be the right CCSID. https://www.ibm.com/support/knowledg...fht8c0056.html


            • #7

              I am trying to convert some data having Hungarian character into base64 encoding. Normal English characters are getting converted correctly, but Hungarian characters are being ignored it seems. I am using base64_encode service program by Scott Klement(link for code below).

              I am giving input to base64_encode as ASCII data.
              wwEncLen = base64_encode(%addr(data):

              I also tried with converting the data to 852 CCSID which supports Hungarian text. And used it as input to base64_encode. But I am not getting the correct value on decode.
              dcl-s data852 varchar(7000000) ccsid(852); data852 = data; /* data in EBCDIC format */ wwEncLen = base64_encode(%addr(data852): %len(%trimr(data852)): %addr(wwEncoded): %size(wwEncoded)); Appreciate any help !


              • #8

                I see some problems in your code, but they don't explain why Hungarian characters would be ignored.

                1. Never use QDCXLATE with QASCII unless you really know what you're doing. Use CCSIDs (like your second example) instead.

                2. You are passing %addr(data852), but data852 is a VARCHAR field. That means the first 4 bytes of the field are the length of the data. You probably don't want to translate the length to ASCII. Use %ADDR(DATA852:*DATA) instead.

                3. The /* */ characters are not a legitimate way to code a comment in RPG.

                These don't fully explain the symptoms you've reported, so there are probably other problems in part of the process that you haven't posted.


                • #9
                  Hello Scott,

                  Thank you for pointing out. My comments below.
                  1. Initially I was trying to convert EBCDIC data containing Hungarian characters using QDCXLATE with QTCPASC initially. But when i tried to reconvert it back the ASCII data to EBCDIC, it gave wrong value. Using QASCII/QEBCDIC was giving correct conversion.
                  2. The /* */ characters I used just to point out in the text here, not in program.
                  3. I tried passing data852 as you mentioned, still I am not getting correct output i.e. the Hungarian characters are still ignored. Below is what I am trying to do.

                  D wbase64xml S 9999999A inz
                  D wwEncoded S 100000A
                  D wwEncLen S 10I 0
                  D base64_value S 100000A varying inz('')
                  D data s 7000000A inz

                  dcl-s data852 varchar(7000000) ccsid(852);
                  len = %len(%trimr(wbase64xml));
                  data = %subst(wbase64xml:1:%len(%trim(wbase64xml)));
                  data852 = data;
                  //convert to base64 encoding
                  wwEncLen = base64_encode(%addr(data852:*data):
                  base64_value = %subst(wwEncoded:1:wwEncLen);

                  Note: The default CCS ID in the system -
                  Coded character set identifier . . . . . . . . . : 65535
                  Default coded character set identifier . . . . . : 870

                  Please help me know where I am doing wrong.



                  • #10
                    It appears as though your input is in teh string wbase64xml, is that correct? Can you provide a value for wbase64xml that we can use to run the code and see the problem?


                    • #11
                      Yes, wbase64xml is the input string. Below is one instance.

                      wbase64xml = 'záróalátét'
                      Correct base64 encoded data = 'esOhcsOzYWzDoXTDqXQ='
                      Through my program encoded data = 'eqByomFsoHSCdA=='



                      • #12
                        When I take the output you say you're getting (eqByomFsoHSCdA==) and run it through a base64 decoder, I get a hex value of 7a a0 72 a2 61 6c a0 74 82 74. I looked these characters up on a CCSID 852 chart, and these are indeed the correct characters. It is not (in your words) "ignoring Hungarian characters".

                        Your second example (the 'corrrect' one according to you -- esOhcsOzYWzDoXTDqXQ=) decodes to 7a c3 a1 72 c3 b3 61 6c c3 a1 74 c3 a9 74, which is not valid CCSID 852. This appears to be UTF-8 (CCSID 1208) rather than CCSID 852. Can you explain why you are converting it to CCSID 852 if your goal is to have UTF-8?

                        I changed your code (and cleaned it up a little bit) and came up with this RPG program:

                             H dftactgrp(*no) bnddir('BASE64')
                              /copy base64_h
                             D wbase64xml      S        9999999A   inz
                             D wwEncoded       S         100000A
                             D wwEncLen        s             10i 0
                               dcl-s datautf8 varchar(7000000) ccsid(1208);
                               wbase64xml = 'záróalátét';
                               datautf8 = %trimr(wbase64xml);
                               wwEncLen = base64_encode( %addr(datautf8 : *data)
                                                       : %len(datautf8)
                                                       : %addr(wwEncoded)
                                                       : %size(wwEncoded) );
                               *inlr = *on;
                        This does, indeed, give the "correct" base64 string of esOhcsOzYWzDoXTDqXQ=

                        You need to decide exactly what it is you are looking for. Is it 852 or 1208?


                        • #13
                          Hello Scott,

                          Thank you for the detailed explanation. I was wrong in assuming since i have Hungarian characters, so i need to convert to CCSID 852. The code given by you works for me.

                          Thank you very much for all your time.