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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
function y = base64encode(x, eol)
%BASE64ENCODE Perform base64 encoding on a string.
%
% BASE64ENCODE(STR, EOL) encode the given string STR. EOL is the line ending
% sequence to use; it is optional and defaults to '\n' (ASCII decimal 10).
% The returned encoded string is broken into lines of no more than 76
% characters each, and each line will end with EOL unless it is empty. Let
% EOL be empty if you do not want the encoded string broken into lines.
%
% STR and EOL don't have to be strings (i.e., char arrays). The only
% requirement is that they are vectors containing values in the range 0-255.
%
% 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.
%
% Examples
% --------
%
% If you want to encode a large file, you should encode it in chunks that are
% a multiple of 57 bytes. This ensures that the base64 lines line up and
% that you do not end up with padding in the middle. 57 bytes of data fills
% one complete base64 line (76 == 57*4/3):
%
% If ifid and ofid are two file identifiers opened for reading and writing,
% respectively, then you can base64 encode the data with
%
% while ~feof(ifid)
% fwrite(ofid, base64encode(fread(ifid, 60*57)));
% end
%
% or, if you have enough memory,
%
% fwrite(ofid, base64encode(fread(ifid)));
%
% See also BASE64DECODE.
% Author: Peter J. Acklam
% Time-stamp: 2004-02-03 21:36:56 +0100
% E-mail: pjacklam@online.no
% URL: http://home.online.no/~pjacklam
% check number of input arguments
error(nargchk(1, 2, nargin));
% make sure we have the EOL value
if nargin < 2
eol = sprintf('\n');
else
if sum(size(eol) > 1) > 1
error('EOL must be a vector.');
end
if any(eol(:) > 255)
error('EOL can not contain values larger than 255.');
end
end
if sum(size(x) > 1) > 1
error('STR must be a vector.');
end
x = uint8(x);
eol = uint8(eol);
ndbytes = length(x); % number of decoded bytes
nchunks = ceil(ndbytes / 3); % number of chunks/groups
nebytes = 4 * nchunks; % number of encoded bytes
% add padding if necessary, to make the length of x a multiple of 3
if rem(ndbytes, 3)
x(end+1 : 3*nchunks) = 0;
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,:)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Now perform the following mapping
%
% 0 - 25 -> A-Z
% 26 - 51 -> a-z
% 52 - 61 -> 0-9
% 62 -> +
% 63 -> /
%
% We could use a mapping vector like
%
% ['A':'Z', 'a':'z', '0':'9', '+/']
%
% but that would require an index vector of class double.
%
z = repmat(uint8(0), size(y));
i = y <= 25; z(i) = 'A' + double(y(i));
i = 26 <= y & y <= 51; z(i) = 'a' - 26 + double(y(i));
i = 52 <= y & y <= 61; z(i) = '0' - 52 + double(y(i));
i = y == 62; z(i) = '+';
i = y == 63; z(i) = '/';
y = z;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Add padding if necessary.
%
npbytes = 3 * nchunks - ndbytes; % number of padding bytes
if npbytes
y(end-npbytes+1 : end) = '='; % '=' is used for padding
end
if isempty(eol)
% reshape to a row vector
y = reshape(y, [1, nebytes]);
else
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
eol = eol(:);
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) = '';
% extract and reshape to row vector
y = reshape(y, 1, m+neolbytes);
end
% output is a character array
y = char(y);
|