/matlab/spm8/@gifti/private/base64encode.m

https://github.com/yuval-harpaz/ft_BIU · Objective C · 159 lines · 135 code · 24 blank · 0 comment · 18 complexity · ea2b8595113aa9bcefca1fc4b8997d13 MD5 · raw file

  1. function y = base64encode(x, eol)
  2. %BASE64ENCODE Perform base64 encoding on a string.
  3. %
  4. % BASE64ENCODE(STR, EOL) encode the given string STR. EOL is the line ending
  5. % sequence to use; it is optional and defaults to '\n' (ASCII decimal 10).
  6. % The returned encoded string is broken into lines of no more than 76
  7. % characters each, and each line will end with EOL unless it is empty. Let
  8. % EOL be empty if you do not want the encoded string broken into lines.
  9. %
  10. % STR and EOL don't have to be strings (i.e., char arrays). The only
  11. % requirement is that they are vectors containing values in the range 0-255.
  12. %
  13. % This function may be used to encode strings into the Base64 encoding
  14. % specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions). The
  15. % Base64 encoding is designed to represent arbitrary sequences of octets in a
  16. % form that need not be humanly readable. A 65-character subset
  17. % ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be represented per
  18. % printable character.
  19. %
  20. % Examples
  21. % --------
  22. %
  23. % If you want to encode a large file, you should encode it in chunks that are
  24. % a multiple of 57 bytes. This ensures that the base64 lines line up and
  25. % that you do not end up with padding in the middle. 57 bytes of data fills
  26. % one complete base64 line (76 == 57*4/3):
  27. %
  28. % If ifid and ofid are two file identifiers opened for reading and writing,
  29. % respectively, then you can base64 encode the data with
  30. %
  31. % while ~feof(ifid)
  32. % fwrite(ofid, base64encode(fread(ifid, 60*57)));
  33. % end
  34. %
  35. % or, if you have enough memory,
  36. %
  37. % fwrite(ofid, base64encode(fread(ifid)));
  38. %
  39. % See also BASE64DECODE.
  40. % Author: Peter J. Acklam
  41. % Time-stamp: 2004-02-03 21:36:56 +0100
  42. % E-mail: pjacklam@online.no
  43. % URL: http://home.online.no/~pjacklam
  44. % check number of input arguments
  45. error(nargchk(1, 2, nargin));
  46. % make sure we have the EOL value
  47. if nargin < 2
  48. eol = ''; %sprintf('\n');
  49. else
  50. if sum(size(eol) > 1) > 1
  51. error('EOL must be a vector.');
  52. end
  53. if any(eol(:) > 255)
  54. error('EOL can not contain values larger than 255.');
  55. end
  56. end
  57. if sum(size(x) > 1) > 1
  58. error('STR must be a vector.');
  59. end
  60. x = uint8(x);
  61. eol = uint8(eol);
  62. ndbytes = length(x); % number of decoded bytes
  63. nchunks = ceil(ndbytes / 3); % number of chunks/groups
  64. nebytes = 4 * nchunks; % number of encoded bytes
  65. % add padding if necessary, to make the length of x a multiple of 3
  66. if rem(ndbytes, 3)
  67. x(end+1 : 3*nchunks) = 0;
  68. end
  69. x = reshape(x, [3, nchunks]); % reshape the data
  70. y = repmat(uint8(0), 4, nchunks); % for the encoded data
  71. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  72. % Split up every 3 bytes into 4 pieces
  73. %
  74. % aaaaaabb bbbbcccc ccdddddd
  75. %
  76. % to form
  77. %
  78. % 00aaaaaa 00bbbbbb 00cccccc 00dddddd
  79. %
  80. y(1,:) = bitshift(x(1,:), -2); % 6 highest bits of x(1,:)
  81. y(2,:) = bitshift(bitand(x(1,:), 3), 4); % 2 lowest bits of x(1,:)
  82. y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4)); % 4 highest bits of x(2,:)
  83. y(3,:) = bitshift(bitand(x(2,:), 15), 2); % 4 lowest bits of x(2,:)
  84. y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6)); % 2 highest bits of x(3,:)
  85. y(4,:) = bitand(x(3,:), 63); % 6 lowest bits of x(3,:)
  86. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  87. % Now perform the following mapping
  88. %
  89. % 0 - 25 -> A-Z
  90. % 26 - 51 -> a-z
  91. % 52 - 61 -> 0-9
  92. % 62 -> +
  93. % 63 -> /
  94. %
  95. % We could use a mapping vector like
  96. %
  97. % ['A':'Z', 'a':'z', '0':'9', '+/']
  98. %
  99. % but that would require an index vector of class double.
  100. %
  101. z = repmat(uint8(0), size(y));
  102. i = y <= 25; z(i) = 'A' + double(y(i));
  103. i = 26 <= y & y <= 51; z(i) = 'a' - 26 + double(y(i));
  104. i = 52 <= y & y <= 61; z(i) = '0' - 52 + double(y(i));
  105. i = y == 62; z(i) = '+';
  106. i = y == 63; z(i) = '/';
  107. y = z;
  108. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  109. % Add padding if necessary.
  110. %
  111. npbytes = 3 * nchunks - ndbytes; % number of padding bytes
  112. if npbytes
  113. y(end-npbytes+1 : end) = '='; % '=' is used for padding
  114. end
  115. if isempty(eol)
  116. % reshape to a row vector
  117. y = reshape(y, [1, nebytes]);
  118. else
  119. nlines = ceil(nebytes / 76); % number of lines
  120. neolbytes = length(eol); % number of bytes in eol string
  121. % pad data so it becomes a multiple of 76 elements
  122. y(nebytes + 1 : 76 * nlines) = 0;
  123. y = reshape(y, 76, nlines);
  124. % insert eol strings
  125. eol = eol(:);
  126. y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines));
  127. % remove padding, but keep the last eol string
  128. m = nebytes + neolbytes * (nlines - 1);
  129. n = (76+neolbytes)*nlines - neolbytes;
  130. y(m+1 : n) = '';
  131. % extract and reshape to row vector
  132. y = reshape(y, 1, m+neolbytes);
  133. end
  134. % output is a character array
  135. y = char(y);