-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbase64encode.m
138 lines (124 loc) · 4.85 KB
/
base64encode.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
function y = base64encode(x, alg, isChunked, url_safe)
%BASE64ENCODE Perform base64 encoding on a string.
% INPUT:
% x - block of data to be encoded. Can be a string or a numeric
% vector containing integers in the range 0-255.
% alg - Algorithm to use: can take values 'java' or 'matlab'. Optional
% variable defaulting to 'java' which is a little faster. If
% 'java' is chosen than core of the code is performed by a call to
% a java library. Optionally all operations can be performed using
% matleb code.
% isChunked - encode output into 76 character blocks. The returned
% encoded string is broken into lines of no more than
% 76 characters each, and each line will end with EOL. Notice that
% if resulting string is saved as part of an xml file, those EOL's
% are often stripped by xmlwrite funtrion prior to saving.
% url_safe - use Modified Base64 for URL applications ('base64url'
% encoding) "Base64 alphabet" ([A-Za-z0-9-_=]).
%
%
% OUTPUT:
% y - character array using only "Base64 alphabet" characters
%
% This function may be used to encode strings into the Base64 encoding
% specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions).
% The Base64 encoding is designed to represent arbitrary sequences of
% octets in a form that need not be humanly readable. A 65-character
% subset ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be
% represented per printable character.
%
% See also BASE64DECODE.
%
% Written by Jarek Tuszynski, SAIC, jaroslaw.w.tuszynski_at_saic.com
%
% Matlab version based on 2004 code by Peter J. Acklam
% E-mail: [email protected]
% URL: http://home.online.no/~pjacklam
% http://home.online.no/~pjacklam/matlab/software/util/datautil/base64encode.m
if nargin<2, alg='java'; end
if nargin<3, isChunked=false; end
if ~islogical(isChunked)
if isnumeric(isChunked)
isChunked=(isChunked>0);
else
isChunked=false;
end
end
if nargin<4, url_safe=false; end
if ~islogical(url_safe)
if isnumeric(url_safe)
url_safe=(url_safe>0);
else
url_safe=false;
end
end
%% if x happen to be a filename than read the file
if (numel(x)<256)
if (exist(x, 'file')==2)
fid = fopen(x,'rb');
x = fread(fid, 'uint8'); % read image file as a raw binary
fclose(fid);
end
end
%% Perform conversion
switch (alg)
case 'java'
base64 = org.apache.commons.codec.binary.Base64;
y = base64.encodeBase64(x, isChunked);
if url_safe
y = strrep(y,'=','-');
y = strrep(y,'/','_');
end
case 'matlab'
%% add padding if necessary, to make the length of x a multiple of 3
x = uint8(x(:));
ndbytes = length(x); % number of decoded bytes
nchunks = ceil(ndbytes / 3); % number of chunks/groups
if rem(ndbytes, 3)>0
x(end+1 : 3*nchunks) = 0; % add padding
end
x = reshape(x, [3, nchunks]); % reshape the data
y = repmat(uint8(0), 4, nchunks); % for the encoded data
%% Split up every 3 bytes into 4 pieces
% aaaaaabb bbbbcccc ccdddddd
% to form
% 00aaaaaa 00bbbbbb 00cccccc 00dddddd
y(1,:) = bitshift(x(1,:), -2); % 6 highest bits of x(1,:)
y(2,:) = bitshift(bitand(x(1,:), 3), 4); % 2 lowest bits of x(1,:)
y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4)); % 4 highest bits of x(2,:)
y(3,:) = bitshift(bitand(x(2,:), 15), 2); % 4 lowest bits of x(2,:)
y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6)); % 2 highest bits of x(3,:)
y(4,:) = bitand(x(3,:), 63); % 6 lowest bits of x(3,:)
%% Perform the mapping
% 0 - 25 -> A-Z
% 26 - 51 -> a-z
% 52 - 61 -> 0-9
% 62 -> +
% 63 -> /
map = ['A':'Z', 'a':'z', '0':'9', '+/'];
if (url_safe), map(63:64)='-_'; end
y = map(y(:)+1);
%% Add padding if necessary.
npbytes = 3 * nchunks - ndbytes; % number of padding bytes
if npbytes>0
y(end-npbytes+1 : end) = '='; % '=' is used for padding
end
%% break into lines with length LineLength
if (isChunked)
eol = sprintf('\n');
nebytes = numel(y);
nlines = ceil(nebytes / 76); % number of lines
neolbytes = length(eol); % number of bytes in eol string
% pad data so it becomes a multiple of 76 elements
y(nebytes + 1 : 76 * nlines) = 0;
y = reshape(y, 76, nlines);
% insert eol strings
y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines));
% remove padding, but keep the last eol string
m = nebytes + neolbytes * (nlines - 1);
n = (76+neolbytes)*nlines - neolbytes;
y(m+1 : n) = [];
end
end
%% reshape to a row vector and make it a character array
y = char(reshape(y, 1, numel(y)));