BookmarkSubscribeRSS Feed
Liliya95
Fluorite | Level 6

Hi!
Running the code causes a truncation error. Although the input file has a length less than the maximum. This is a test code, but in fact there will come texts of large dimension.
What could be the reason?

 

%macro test;

%let temp=PGVudE5hbT7QntCR0KnQldCh0KLQktCeINChINCe0JPQoNCQ0J3QmNCn0JXQndCd0J7QmSDQntCi0JLQldCi0KHQotCS0JXQndCd0J7QodCi0KzQriAi0KHQotCg0J7QmNCi0JXQm9Cs0J3QkNCvINCa0J7QnNCf0JDQndCY0K8gItCS0JjQlCI8L2VudE5hbT4=;

		%put temp=&temp;
        %let decodedata =%qsysfunc(inputc(&temp,$base64x32767));
		%put decodedata=&decodedata;
		%let DOCFILE = &TEST/tesе/2.xml;
		FILENAME DOCFILE "&DOCFILE" encoding='wcyrillic' LRECL=32767;

		data _null_;		  
           file DOCFILE LRECL=32767 recfm=f;
           length temp $32767;
           put "&decodedata";		  
        run;

 

%mend test;


%test;
4 REPLIES 4
andreas_lds
Jade | Level 19

It has been said many times: don't put data in macro-variables.

 

Seems to work fine:

data work.have;
   temp = "PGVudE5hbT7QntCR0KnQldCh0KLQktCeINChINCe0JPQoNCQ0J3QmNCn0JXQndCd0J7QmSDQntCi0JLQldCi0KHQotCS0JXQndCd0J7QodCi0KzQriAi0KHQotCg0J7QmNCi0JXQm9Cs0J3QkNCvINCa0J7QnNCf0JDQndCY0K8gItCS0JjQlCI8L2VudE5hbT4=";
   decodeData = input(temp, $base64x32767.);
run;


filename docfile "&TEST/tesе/2.xml" encoding='wcyrillic' lrecl=32767;

data _null_;
   set have;
   file docfile lrecl=32767 recfm=f;
   put decodedata;
run;
Sharkman
Calcite | Level 5
Sorry if it has been said many times but the code doesn't work. SAS truncate the base64 text. The code have 17699 characters.
Tom
Super User Tom
Super User

What are you trying to do? Your posted code does not make much sense.  Why are you defining a variable in the data step that you never use?

 

Why are you trying to work with BASE64 text in macro variables?

You need to use %QSYSFUNC() but that will add macro quoting to the trailing spaces produced by using an informat with a width that is longer than needed.

1    %let
1  ! temp=PGVudE5hbT7QntCR0KnQldCh0KLQktCeINChINCe0JPQoNCQ0J3QmNCn0JXQndC
1  ! d0J7QmSDQntCi0JLQldCi0KHQotCS0JXQndCd0J7QodCi0KzQriAi0KHQotCg0J7QmNC
1  ! i0JXQm9Cs0J3QkNCvINCa0J7QnNCf0JDQndCY0K8gItCS0JjQlCI8L2VudE5hbT4=;
2
3    %put %length(&temp);
196
4    %let decoded=%qsysfunc(inputc(&temp,$base64x32767.));
5    %put %length(&decoded);
32767

For an encoded string of 196 bytes the result is a string of 147 bytes.  3*196/4= 147.

So here is what you need to do.

1) Use the length of the ENCODED string in the INFORMAT.  But this will return a string of that length (so padded with 49 (196-147) extra spaces).

2) So then use the %QSUBSTR() to remove the extra spaces.

109  %let
109! temp=PGVudE5hbT7QntCR0KnQldCh0KLQktCeINChINCe0JPQoNCQ0J3QmNCn0JXQndC
109! d0J7QmSDQntCi0JLQldCi0KHQotCS0JXQndCd0J7QodCi0KzQriAi0KHQotCg0J7QmNC
109! i0JXQm9Cs0J3QkNCvINCa0J7QnNCf0JDQndCY0K8gItCS0JjQlCI8L2VudE5hbT4=;
110  %let inlength=%length(&temp);
111  %let outlength=%eval((&inlength+3)/4*3);
112  %put &=inlength &=outlength;
INLENGTH=196 OUTLENGTH=147
113  %let
113! decoded=%qsubstr(%qsysfunc(inputc(&temp,$base64x&inlength)),1,&outle
113! ngth);
114  %put &=decoded;
DECODED=<entNam>ОБЩЕСТВО С ОГРАНИЧЕННОЙ
ОТВЕТСТВЕННОСТЬЮ "СТРОИТЕЛЬНАЯ
КОМПАНИЯ "ВИД"</entNam>
115  %put %length(&decoded);
147

 

Tom
Super User Tom
Super User

Note also that if the encoded string is not an exact multiple of 4 bytes long then you need to append equal signs until it is so that the BASE64 string has the right number of bits to be split back into base256 strings.

Example:

217  data test;
218    x='AB';
219    encode = put(x,$base64x4.);
220    put encode=;
221  run;

encode=QUI=
NOTE: The data set WORK.TEST has 1 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


222
223
224  %let coded=QUI;
225  %let raw_length=%length(&coded);
226  %let actual_length=%eval((&raw_length+3)/4*4);
227  %put &=raw_length &=actual_length ;
RAW_LENGTH=3 ACTUAL_LENGTH=4
228  %put %sysfunc(inputc(&coded,$base64x&raw_length));

229  %put %sysfunc(inputc(&coded,$base64x&actual_length));

230  %put %sysfunc(inputc(&coded===,$base64x&actual_length));
AB

So make sure to figure out the right length to use and to append some equal signs.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 1240 views
  • 3 likes
  • 4 in conversation