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);