]> Creatis software - CreaPhase.git/blob - octave_packages/strings-1.1.0/base64decode.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / strings-1.1.0 / base64decode.m
1 ## Copyright (C) 2007 Muthiah Annamalai <muthiah.annamalai@uta.edu>
2 ##
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
6 ## version.
7 ##
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 ## details.
12 ##
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
15
16 ## -*- texinfo -*-
17 ## @deftypefn {Function File} {@var{rval} =} base64decode (@var{code})
18 ## @deftypefnx {Function File} {@var{rval} =} base64decode (@var{code}, @var{as_string})
19 ## Convert a base64 @var{code}  (a string of printable characters according to RFC 2045) 
20 ## into the original ASCII data set of range 0-255. If option @var{as_string} is 
21 ## passed, the return value is converted into a string.
22 ##
23 ## @example
24 ## @group
25 ##           ##base64decode(base64encode('Hakuna Matata'),true)
26 ##           base64decode('SGFrdW5hIE1hdGF0YQ==',true)
27 ##           ##returns 'Hakuna Matata'
28 ## @end group
29 ## @end example
30 ##
31 ## See: http://www.ietf.org/rfc/rfc2045.txt
32 ##
33 ## @seealso {base64encode}
34 ## @end deftypefn
35
36 function z = base64decode (X, as_string)
37   if (nargin < 1 )
38     print_usage;
39   elseif nargin == 1
40     as_string=false;
41   endif
42
43   if ( any(X(:) < 0) || any(X(:) > 255))
44     error("base64decode is expecting integers in the range 0 .. 255");
45   endif
46
47   ## decompose strings into the 4xN matrices 
48   ## formatting issues.
49   if( rows(X) == 1 )
50     Y=[];
51     L=length(X);
52     for z=4:4:L
53         Y=[Y X(z-3:z)']; #keep adding columns
54     end
55     if min(size(Y))==1
56         Y=reshape(Y,[L, 1]);
57     else
58         Y=reshape(Y,[4,L/4]);
59     end
60     X=Y;
61     Y=[];
62   end
63
64   X = toascii(X);
65   Xa= X;
66
67   ## Work backwards. Starting at step in table,
68   ## lookup the index of the element in the table.
69
70   ## 6-bit encoding table, plus 1 for padding
71   ## 26*2 + 10 + 2 + 1  = 64 + 1, '=' is EOF stop mark.
72   table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
73
74   S=size(X);
75   SRows=S(1);
76   SCols=S(2);
77   Y=zeros(S);
78
79   ## decode the incoming matrix & 
80   ## write the values into Va matrix.
81   Va = -1*ones(size(Xa));
82
83   iAZ = (Xa >= 'A').*(Xa <= 'Z') > 0; 
84   Va(iAZ)=Xa(iAZ)-'A';
85
86   iaz = (Xa >= 'a').*(Xa <= 'z') > 0;
87   Va(iaz)=Xa(iaz)-'a'+26;
88
89   i09 = (Xa >= '0').*(Xa <= '9') > 0;
90   Va(i09)=Xa(i09)-'0'+52;
91
92   is = (Xa == '/') ;  Va(is) = 63;
93   ip = (Xa == '+') ;  Va(ip) = 62;
94   ieq = (Xa == '=') ;  Va(ieq) = 0;
95   clear is; clear ieq; clear ip; clear i09;
96   clear iaz; clear iAZ;  clear Xa; clear X;
97
98   Y=Va; clear Va;
99   Y1=Y(1,:);
100   if (SRows > 1)
101      Y2=Y(2,:);
102   else 
103      Y2=zeros(1,SCols);
104   end;
105
106   if (SRows > 2)
107      Y3=Y(3,:);
108   else 
109      Y3=zeros(1,SCols);
110   end;
111
112   if (SRows > 3)
113      Y4=Y(4,:);
114   else 
115      Y4=zeros(1,SCols);
116   end;
117
118   ## +1 not required due to ASCII subtraction
119   ## actual decoding work
120   b1 = Y1*4 + fix(Y2/16);
121   b2 = mod(Y2,16)*16+fix(Y3/4);
122   b3 = mod(Y3,4)*64 + Y4;
123
124   ZEROS=sum(sum(Y==0));
125   L=length(b1)*3;
126   z=zeros(1,L);
127   z(1:3:end)=b1;
128   if (SRows > 1)
129      z(2:3:end)=b2;
130   else
131      z(2:3:end)=[];
132   end;
133
134   if (SRows > 2)
135      z(3:3:end)=b3;
136   else
137      z(3:3:end)=[];
138   end
139
140   ## FIXME
141   ## is this expected behaviour?
142   if ( as_string )
143     L=length(z);
144     while ( ( L > 0) && ( z(L)==0 ) )
145       L=L-1;
146     end
147     z=char(z(1:L));
148   end
149
150 endfunction
151
152 %!assert(base64decode(base64encode('Hakuna Matata'),true),'Hakuna Matata')
153 %!assert(base64decode(base64encode([1:255])),[1:255])
154 %!assert(base64decode(base64encode('taken'),true),'taken')
155 %!assert(base64decode(base64encode('sax'),true),'sax')
156 %!assert(base64decode(base64encode('H'),true),'H')
157 %!assert(base64decode(base64encode('Ta'),true),'Ta')