0
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
1 function submitWeb(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
2 %SUBMITWEB Generates a base64 encoded string for web-based submissions |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
3 % SUBMITWEB() will generate a base64 encoded string so that you can submit your |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
4 % solutions via a web form |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
5 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
6 fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
7 homework_id()); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
8 if ~exist('partId', 'var') || isempty(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
9 partId = promptPart(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
10 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
11 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
12 % Check valid partId |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
13 partNames = validParts(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
14 if ~isValidPartId(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
15 fprintf('!! Invalid homework part selected.\n'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
16 fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
17 fprintf('!! Submission Cancelled\n'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
18 return |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
19 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
20 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
21 [login] = loginPrompt(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
22 if isempty(login) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
23 fprintf('!! Submission Cancelled\n'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
24 return |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
25 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
26 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
27 [result] = submitSolution(login, partId, output(partId), ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
28 source(partId)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
29 result = base64encode(result); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
30 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
31 fprintf('\nSave as submission file [submit_ex%s_part%d.txt]: ', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
32 homework_id(), partId); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
33 saveAsFile = input('', 's'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
34 if (isempty(saveAsFile)) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
35 saveAsFile = sprintf('submit_ex%s_part%d.txt', homework_id(), partId); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
36 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
37 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
38 fid = fopen(saveAsFile, 'w'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
39 if (fid) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
40 fwrite(fid, result); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
41 fclose(fid); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
42 fprintf('\nSaved your solutions to %s.\n\n', saveAsFile); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
43 fprintf(['You can now submit your solutions through the web \n' ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
44 'form in the programming exercises. Select the corresponding \n' ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
45 'programming exercise to access the form.\n']); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
46 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
47 else |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
48 fprintf('Unable to save to %s\n\n', saveAsFile); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
49 fprintf(['You can create a submission file by saving the \n' ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
50 'following text in a file: (press enter to continue)\n\n']); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
51 pause; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
52 fprintf(result); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
53 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
54 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
55 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
56 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
57 % ================== CONFIGURABLES FOR EACH HOMEWORK ================== |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
58 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
59 function id = homework_id() |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
60 id = '5'; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
61 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
62 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
63 function [partNames] = validParts() |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
64 partNames = { 'Regularized Linear Regression Cost Function', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
65 'Regularized Linear Regression Gradient', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
66 'Learning Curve', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
67 'Polynomial Feature Mapping' ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
68 'Validation Curve' ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
69 }; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
70 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
71 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
72 function srcs = sources() |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
73 % Separated by part |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
74 srcs = { { 'linearRegCostFunction.m' }, ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
75 { 'linearRegCostFunction.m' }, ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
76 { 'learningCurve.m' }, ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
77 { 'polyFeatures.m' }, ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
78 { 'validationCurve.m' } }; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
79 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
80 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
81 function out = output(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
82 % Random Test Cases |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
83 X = [ones(10,1) sin(1:1.5:15)' cos(1:1.5:15)']; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
84 y = sin(1:3:30)'; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
85 Xval = [ones(10,1) sin(0:1.5:14)' cos(0:1.5:14)']; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
86 yval = sin(1:10)'; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
87 if partId == 1 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
88 [J] = linearRegCostFunction(X, y, [0.1 0.2 0.3]', 0.5); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
89 out = sprintf('%0.5f ', J); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
90 elseif partId == 2 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
91 [J, grad] = linearRegCostFunction(X, y, [0.1 0.2 0.3]', 0.5); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
92 out = sprintf('%0.5f ', grad); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
93 elseif partId == 3 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
94 [error_train, error_val] = ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
95 learningCurve(X, y, Xval, yval, 1); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
96 out = sprintf('%0.5f ', [error_train(:); error_val(:)]); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
97 elseif partId == 4 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
98 [X_poly] = polyFeatures(X(2,:)', 8); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
99 out = sprintf('%0.5f ', X_poly); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
100 elseif partId == 5 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
101 [lambda_vec, error_train, error_val] = ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
102 validationCurve(X, y, Xval, yval); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
103 out = sprintf('%0.5f ', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
104 [lambda_vec(:); error_train(:); error_val(:)]); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
105 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
106 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
107 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
108 % ========================= SUBMIT HELPERS ========================= |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
109 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
110 function src = source(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
111 src = ''; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
112 src_files = sources(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
113 if partId <= numel(src_files) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
114 flist = src_files{partId}; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
115 for i = 1:numel(flist) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
116 fid = fopen(flist{i}); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
117 while ~feof(fid) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
118 line = fgets(fid); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
119 src = [src line]; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
120 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
121 fclose(fid); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
122 src = [src '||||||||']; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
123 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
124 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
125 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
126 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
127 function ret = isValidPartId(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
128 partNames = validParts(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
129 ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
130 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
131 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
132 function partId = promptPart() |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
133 fprintf('== Select which part(s) to submit:\n', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
134 homework_id()); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
135 partNames = validParts(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
136 srcFiles = sources(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
137 for i = 1:numel(partNames) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
138 fprintf('== %d) %s [', i, partNames{i}); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
139 fprintf(' %s ', srcFiles{i}{:}); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
140 fprintf(']\n'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
141 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
142 fprintf('\nEnter your choice [1-%d]: ', ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
143 numel(partNames)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
144 selPart = input('', 's'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
145 partId = str2num(selPart); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
146 if ~isValidPartId(partId) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
147 partId = -1; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
148 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
149 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
150 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
151 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
152 function [result, str] = submitSolution(email, part, output, source) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
153 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
154 result = ['a:5:{' ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
155 p_s('homework') p_s64(homework_id()) ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
156 p_s('part') p_s64(part) ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
157 p_s('email') p_s64(email) ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
158 p_s('output') p_s64(output) ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
159 p_s('source') p_s64(source) ... |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
160 '}']; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
161 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
162 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
163 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
164 function s = p_s(str) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
165 s = ['s:' num2str(numel(str)) ':"' str '";']; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
166 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
167 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
168 function s = p_s64(str) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
169 str = base64encode(str, ''); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
170 s = ['s:' num2str(numel(str)) ':"' str '";']; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
171 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
172 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
173 % =========================== LOGIN HELPERS =========================== |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
174 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
175 function [login] = loginPrompt() |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
176 % Prompt for password |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
177 [login] = basicPrompt(); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
178 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
179 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
180 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
181 function [login] = basicPrompt() |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
182 login = input('Login (Email address): ', 's'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
183 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
184 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
185 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
186 % =========================== Base64 Encoder ============================ |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
187 % Thanks to Peter John Acklam |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
188 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
189 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
190 function y = base64encode(x, eol) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
191 %BASE64ENCODE Perform base64 encoding on a string. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
192 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
193 % BASE64ENCODE(STR, EOL) encode the given string STR. EOL is the line ending |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
194 % sequence to use; it is optional and defaults to '\n' (ASCII decimal 10). |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
195 % The returned encoded string is broken into lines of no more than 76 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
196 % characters each, and each line will end with EOL unless it is empty. Let |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
197 % EOL be empty if you do not want the encoded string broken into lines. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
198 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
199 % STR and EOL don't have to be strings (i.e., char arrays). The only |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
200 % requirement is that they are vectors containing values in the range 0-255. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
201 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
202 % This function may be used to encode strings into the Base64 encoding |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
203 % specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions). The |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
204 % Base64 encoding is designed to represent arbitrary sequences of octets in a |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
205 % form that need not be humanly readable. A 65-character subset |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
206 % ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be represented per |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
207 % printable character. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
208 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
209 % Examples |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
210 % -------- |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
211 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
212 % If you want to encode a large file, you should encode it in chunks that are |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
213 % a multiple of 57 bytes. This ensures that the base64 lines line up and |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
214 % that you do not end up with padding in the middle. 57 bytes of data fills |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
215 % one complete base64 line (76 == 57*4/3): |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
216 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
217 % If ifid and ofid are two file identifiers opened for reading and writing, |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
218 % respectively, then you can base64 encode the data with |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
219 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
220 % while ~feof(ifid) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
221 % fwrite(ofid, base64encode(fread(ifid, 60*57))); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
222 % end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
223 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
224 % or, if you have enough memory, |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
225 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
226 % fwrite(ofid, base64encode(fread(ifid))); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
227 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
228 % See also BASE64DECODE. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
229 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
230 % Author: Peter John Acklam |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
231 % Time-stamp: 2004-02-03 21:36:56 +0100 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
232 % E-mail: pjacklam@online.no |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
233 % URL: http://home.online.no/~pjacklam |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
234 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
235 if isnumeric(x) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
236 x = num2str(x); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
237 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
238 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
239 % make sure we have the EOL value |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
240 if nargin < 2 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
241 eol = sprintf('\n'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
242 else |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
243 if sum(size(eol) > 1) > 1 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
244 error('EOL must be a vector.'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
245 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
246 if any(eol(:) > 255) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
247 error('EOL can not contain values larger than 255.'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
248 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
249 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
250 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
251 if sum(size(x) > 1) > 1 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
252 error('STR must be a vector.'); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
253 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
254 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
255 x = uint8(x); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
256 eol = uint8(eol); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
257 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
258 ndbytes = length(x); % number of decoded bytes |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
259 nchunks = ceil(ndbytes / 3); % number of chunks/groups |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
260 nebytes = 4 * nchunks; % number of encoded bytes |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
261 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
262 % add padding if necessary, to make the length of x a multiple of 3 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
263 if rem(ndbytes, 3) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
264 x(end+1 : 3*nchunks) = 0; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
265 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
266 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
267 x = reshape(x, [3, nchunks]); % reshape the data |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
268 y = repmat(uint8(0), 4, nchunks); % for the encoded data |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
269 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
270 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
271 % Split up every 3 bytes into 4 pieces |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
272 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
273 % aaaaaabb bbbbcccc ccdddddd |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
274 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
275 % to form |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
276 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
277 % 00aaaaaa 00bbbbbb 00cccccc 00dddddd |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
278 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
279 y(1,:) = bitshift(x(1,:), -2); % 6 highest bits of x(1,:) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
280 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
281 y(2,:) = bitshift(bitand(x(1,:), 3), 4); % 2 lowest bits of x(1,:) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
282 y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4)); % 4 highest bits of x(2,:) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
283 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
284 y(3,:) = bitshift(bitand(x(2,:), 15), 2); % 4 lowest bits of x(2,:) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
285 y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6)); % 2 highest bits of x(3,:) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
286 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
287 y(4,:) = bitand(x(3,:), 63); % 6 lowest bits of x(3,:) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
288 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
290 % Now perform the following mapping |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
291 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
292 % 0 - 25 -> A-Z |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
293 % 26 - 51 -> a-z |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
294 % 52 - 61 -> 0-9 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
295 % 62 -> + |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
296 % 63 -> / |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
297 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
298 % We could use a mapping vector like |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
299 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
300 % ['A':'Z', 'a':'z', '0':'9', '+/'] |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
301 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
302 % but that would require an index vector of class double. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
303 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
304 z = repmat(uint8(0), size(y)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
305 i = y <= 25; z(i) = 'A' + double(y(i)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
306 i = 26 <= y & y <= 51; z(i) = 'a' - 26 + double(y(i)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
307 i = 52 <= y & y <= 61; z(i) = '0' - 52 + double(y(i)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
308 i = y == 62; z(i) = '+'; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
309 i = y == 63; z(i) = '/'; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
310 y = z; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
311 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
313 % Add padding if necessary. |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
314 % |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
315 npbytes = 3 * nchunks - ndbytes; % number of padding bytes |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
316 if npbytes |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
317 y(end-npbytes+1 : end) = '='; % '=' is used for padding |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
318 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
319 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
320 if isempty(eol) |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
321 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
322 % reshape to a row vector |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
323 y = reshape(y, [1, nebytes]); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
324 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
325 else |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
326 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
327 nlines = ceil(nebytes / 76); % number of lines |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
328 neolbytes = length(eol); % number of bytes in eol string |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
329 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
330 % pad data so it becomes a multiple of 76 elements |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
331 y = [y(:) ; zeros(76 * nlines - numel(y), 1)]; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
332 y(nebytes + 1 : 76 * nlines) = 0; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
333 y = reshape(y, 76, nlines); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
334 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
335 % insert eol strings |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
336 eol = eol(:); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
337 y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines)); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
338 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
339 % remove padding, but keep the last eol string |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
340 m = nebytes + neolbytes * (nlines - 1); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
341 n = (76+neolbytes)*nlines - neolbytes; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
342 y(m+1 : n) = ''; |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
343 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
344 % extract and reshape to row vector |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
345 y = reshape(y, 1, m+neolbytes); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
346 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
347 end |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
348 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
349 % output is a character array |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
350 y = char(y); |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
351 |
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
352 end |