Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: test/base64_test.dart

Issue 1169453002: Add an option for percent-encoding of the padding character to Base64Codec (Closed) Base URL: https://github.com/dart-lang/crypto.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« lib/src/base64.dart ('K') | « lib/src/crypto_utils.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // Library tag to allow the test to run on Dartium. 5 // Library tag to allow the test to run on Dartium.
6 library base64_test; 6 library base64_test;
7 7
8 import 'dart:math'; 8 import 'dart:math';
9 import 'dart:async';
9 10
10 import "package:crypto/crypto.dart"; 11 import "package:crypto/crypto.dart";
11 import "package:test/test.dart"; 12 import "package:test/test.dart";
12 13
13 void main() { 14 void main() {
14 test('encoder', _testEncoder); 15 test('encoder', _testEncoder);
15 test('decoder', _testDecoder); 16 test('decoder', _testDecoder);
16 test('decoder for malformed input', _testDecoderForMalformedInput); 17 test('decoder for malformed input', _testDecoderForMalformedInput);
17 test('encode decode lists', _testEncodeDecodeLists); 18 test('encode decode lists', _testEncodeDecodeLists);
18 test('url safe encode-decode', _testUrlSafeEncodeDecode); 19 test('url safe encode-decode', _testUrlSafeEncodeDecode);
20 test('consistent safe/unsafe character decoding',
21 _testConsistentSafeUnsafeDecode);
22 test('percent-encoded padding character encode-decode',
23 _testPaddingCharacter);
24 test('streaming encoder', _testStreamingEncoder);
25 test('streaming decoder', _testStreamingDecoder);
26 test('streaming decoder for malformed input',
27 _testStreamingDecoderForMalformedInput);
28 test('streaming encoder for different decompositions of a list of bytes',
29 _testStreamingEncoderForDecompositions);
30 test('streaming decoder for different decompositions of a string',
31 _testStreamingDecoderForDecompositions);
32 test('consistent safe/unsafe character streaming decoding',
33 _testConsistentSafeUnsafeStreamDecode);
34 test('streaming for encoded padding character',
35 _testStreamingForEncodedPadding);
36 test('old api', _testOldApi);
37 test('url safe streaming encoder/decoder', _testUrlSafeStreaming);
19 test('performance', _testPerformance); 38 test('performance', _testPerformance);
39
40
20 } 41 }
21 42
22 // Data from http://tools.ietf.org/html/rfc4648. 43 // Data from http://tools.ietf.org/html/rfc4648.
23 const _INPUTS = 44 const _INPUTS =
24 const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar']; 45 const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar'];
25 const _RESULTS = 46 const _RESULTS =
26 const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy']; 47 const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy'];
27 48
49 const _PADDING_INPUT = const [2, 8];
50
51 var _STREAMING_ENCODER_INPUT =
52 [[102, 102], [111, 102],
53 [111, 111, 102, 111, 111, 98, 102, 111,
54 111, 98, 97, 102, 111, 111, 98, 97, 114]];
55
56 const _STREAMING_ENCODED = 'ZmZvZm9vZm9vYmZvb2JhZm9vYmFy';
57 const _STREAMING_DECODER_INPUT =
58 const ['YmFz', 'ZTY', '0I', 'GRlY29kZXI='];
59 const _STREAMING_DECODED =
60 const [98, 97, 115, 101, 54, 52, 32, 100, 101, 99, 111, 100, 101, 114];
61 const _STREAMING_DECODER_INPUT_FOR_ZEROES =
62 const ['AAAA', 'AAA=', 'AA==', ''];
63 var _STREAMING_DECODED_ZEROES = [0, 0, 0, 0, 0, 0];
64
65 var _DECOMPOSITIONS_FOR_DECODING = [
66 ["A", "", "BCD"], ["A", "BCD", "", ""], ["A", "B", "", "", "CD", ""],
67 ["", "A", "BC", "", "D"], ["", "AB", "C", "", "", "D"], ["AB", "CD", ""],
68 ["", "ABC", "", "D"], ["", "ABC", "D", ""], ["", "", "ABCD", ""],
69 ["A", "B", "C", "D"], ["", "A", "B", "C", "D", ""],
70 ["", "A", "B", "", "", "C", "", "D", ""]];
71
72 const _DECOMPOSITION_DECODED = const [0, 16, 131];
73
74 var _DECOMPOSITIONS_FOR_ENCODING = [
75 [[196, 16], [], [158], [196]],
76 [[196, 16], [158, 196], [], []],
77 [[196], [], [16], [], [], [158], [], [196]],
78 [[196], [], [16], [158, 196], [], []],
79 [[], [196], [], [], [16, 158], [], [196]],
80 [[], [196], [16, 158, 196], []],
81 [[196, 16, 158], [], [], [196]],
82 [[196, 16, 158], [], [196], []],
83 [[196, 16, 158, 196], [], [], []]];
84
85 const _DECOMPOSITION_ENCODED = 'xBCexA==';
86
87 const _INCONSISTENT_SAFE_RESULT = 'A+_x';
88
89 const _INCONSISTENT_SAFE_STREAMING_RESULT = const ['A+AAA', '_x='];
90
28 // Test data with only zeroes. 91 // Test data with only zeroes.
29 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []]; 92 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []];
30 const _RESULTS_WITH_ZEROS = const ['AAAA', 'AAA=', 'AA==', '']; 93 const _RESULTS_WITH_ZEROS = const ['AAAA', 'AAA=', 'AA==', ''];
31 94
32 const _LONG_LINE = 95 const _LONG_LINE =
33 "Man is distinguished, not only by his reason, but by this singular " 96 "Man is distinguished, not only by his reason, but by this singular "
34 "passion from other animals, which is a lust of the mind, that by a " 97 "passion from other animals, which is a lust of the mind, that by a "
35 "perseverance of delight in the continued and indefatigable generation " 98 "perseverance of delight in the continued and indefatigable generation "
36 "of knowledge, exceeds the short vehemence of any carnal pleasure."; 99 "of knowledge, exceeds the short vehemence of any carnal pleasure.";
37 100
(...skipping 16 matching lines...) Expand all
54 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" 117 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
55 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" 118 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm"
56 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" 119 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
57 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" 120 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX"
58 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" 121 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
59 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" 122 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm"
60 "5hbCBwbGVhc3VyZS4="; 123 "5hbCBwbGVhc3VyZS4=";
61 124
62 void _testEncoder() { 125 void _testEncoder() {
63 for (var i = 0; i < _INPUTS.length; i++) { 126 for (var i = 0; i < _INPUTS.length; i++) {
64 expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]); 127 expect(BASE64.encode(_INPUTS[i].codeUnits), _RESULTS[i]);
65 } 128 }
66 for (var i = 0; i < inputsWithZeroes.length; i++) { 129 for (var i = 0; i < inputsWithZeroes.length; i++) {
67 expect(CryptoUtils.bytesToBase64(inputsWithZeroes[i]), 130 expect(BASE64.encode(inputsWithZeroes[i]),
68 _RESULTS_WITH_ZEROS[i]); 131 _RESULTS_WITH_ZEROS[i]);
69 } 132 }
70 expect( 133 expect(BASE64.encode(_LONG_LINE.codeUnits, addLineSeparator : true),
71 CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits, addLineSeparator : true), 134 _LONG_LINE_RESULT);
72 _LONG_LINE_RESULT); 135 expect(BASE64.encode(_LONG_LINE.codeUnits),
73 expect(CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits), 136 _LONG_LINE_RESULT_NO_BREAK);
74 _LONG_LINE_RESULT_NO_BREAK);
75 } 137 }
76 138
77 void _testDecoder() { 139 void _testDecoder() {
78 for (var i = 0; i < _RESULTS.length; i++) { 140 for (var i = 0; i < _RESULTS.length; i++) {
79 expect( 141 expect(
80 new String.fromCharCodes(CryptoUtils.base64StringToBytes(_RESULTS[i])), 142 new String.fromCharCodes(BASE64.decode(_RESULTS[i])),
81 _INPUTS[i]); 143 _INPUTS[i]);
82 } 144 }
145
83 for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) { 146 for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) {
84 expect(CryptoUtils.base64StringToBytes(_RESULTS_WITH_ZEROS[i]), 147 expect(BASE64.decode(_RESULTS_WITH_ZEROS[i]),
85 inputsWithZeroes[i]); 148 inputsWithZeroes[i]);
86 } 149 }
87 var longLineDecoded = CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT); 150
151 var longLineDecoded = BASE64.decode(_LONG_LINE_RESULT);
88 expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE); 152 expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE);
89 var longLineResultNoBreak = 153
90 CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT); 154 var longLineResultNoBreak = BASE64.decode(_LONG_LINE_RESULT);
91 expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE); 155 expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE);
92 } 156 }
93 157
158 void _testPaddingCharacter() {
159 var encoded = BASE64.encode(_PADDING_INPUT, encodePaddingCharacter: true);
160 expect(encoded, 'Agg%3D');
161 expect(BASE64.decode(encoded), _PADDING_INPUT);
162 }
163
164 Future _testStreamingEncoder() async {
165 expect(
166 await new Stream.fromIterable(_STREAMING_ENCODER_INPUT)
167 .transform(BASE64.encoder)
168 .join(),
169 _STREAMING_ENCODED);
170 }
171
172 Future _testStreamingDecoder() async {
173 expect(
174 await new Stream.fromIterable(_STREAMING_DECODER_INPUT)
175 .transform(BASE64.decoder)
176 .expand((l) => l)
177 .toList(),
178 _STREAMING_DECODED);
179
180 expect(
181 await new Stream.fromIterable(_STREAMING_DECODER_INPUT_FOR_ZEROES)
182 .transform(BASE64.decoder)
183 .expand((l) => l)
184 .toList(),
185 _STREAMING_DECODED_ZEROES);
186 }
187
188 Future _testStreamingDecoderForMalformedInput() async {
189 expect(new Stream.fromIterable(['ABz'])
190 .transform(BASE64.decoder)
191 .toList(),
192 throwsFormatException);
193
194 expect(new Stream.fromIterable(['AB', 'Lx', 'z', 'xx'])
195 .transform(BASE64.decoder)
196 .toList(),
197 throwsFormatException);
198 }
199
200 Future _testStreamingEncoderForDecompositions() async {
201 for(var decomposition in _DECOMPOSITIONS_FOR_ENCODING) {
202 expect(
203 await new Stream.fromIterable(decomposition)
204 .transform(BASE64.encoder)
205 .join(),
206 _DECOMPOSITION_ENCODED);
207 }
208 }
209
210 Future _testStreamingDecoderForDecompositions() async {
211 for(var decomposition in _DECOMPOSITIONS_FOR_DECODING) {
212 expect(
213 await new Stream.fromIterable(decomposition)
214 .transform(BASE64.decoder)
215 .expand((x) => x)
216 .toList(),
217 _DECOMPOSITION_DECODED);
218 }
219 }
220
94 void _testDecoderForMalformedInput() { 221 void _testDecoderForMalformedInput() {
95 expect(() { 222 expect(() {
96 CryptoUtils.base64StringToBytes('AB~'); 223 BASE64.decode('AB~');
97 }, throwsFormatException); 224 }, throwsFormatException);
98 225
99 expect(() { 226 expect(() {
100 CryptoUtils.base64StringToBytes('A'); 227 BASE64.decode('A');
101 }, throwsFormatException); 228 }, throwsFormatException);
102 } 229 }
103 230
231 Future _testUrlSafeStreaming() async {
232 String encUrlSafe = '-_A=';
233 List<List<int>> dec = [BASE64.decode('+/A=')];
234 var streamedResult = await new Stream.fromIterable(dec)
235 .transform(new Base64Encoder(urlSafe: true)).join();
236
237 expect(streamedResult, encUrlSafe);
238 }
239
240 void _testConsistentSafeUnsafeDecode() {
241 expect(() {
242 BASE64.decode(_INCONSISTENT_SAFE_RESULT);
243 }, throwsFormatException);
244 }
245
246 Future _testConsistentSafeUnsafeStreamDecode() {
247 expect(new Stream.fromIterable(_INCONSISTENT_SAFE_STREAMING_RESULT)
248 .transform(BASE64.decoder)
249 .toList(),
250 throwsFormatException);
251 }
252
253 Future _testStreamingForEncodedPadding() async {
254 List<String> withEncodedPadding = ['AA%', '3D', '%', '3', 'DEFGZ'];
255 List<int> decoded = BASE64.decode('AA==EFGZ');
256 var streamedResult = await new Stream.fromIterable(withEncodedPadding)
257 .transform(BASE64.decoder).expand((x) => x).toList();
258
259 expect(streamedResult, decoded);
260 }
261
104 void _testUrlSafeEncodeDecode() { 262 void _testUrlSafeEncodeDecode() {
105 List<int> decUrlSafe = CryptoUtils.base64StringToBytes('-_A='); 263 List<int> decUrlSafe = BASE64.decode('-_A=');
106 List<int> dec = CryptoUtils.base64StringToBytes('+/A='); 264 List<int> dec = BASE64.decode('+/A=');
107 expect(decUrlSafe, orderedEquals(dec)); 265 expect(decUrlSafe, orderedEquals(dec));
108 expect(CryptoUtils.bytesToBase64(dec, urlSafe: true), '-_A='); 266 expect(BASE64.encode(dec, urlSafe: true), '-_A=');
109 expect(CryptoUtils.bytesToBase64(dec), '+/A='); 267 expect(BASE64.encode(dec), '+/A=');
110 } 268 }
111 269
112 void _testEncodeDecodeLists() { 270 void _testEncodeDecodeLists() {
113 for (int i = 0; i < 10; i++) { 271 for (int i = 0; i < 10; i++) {
114 for (int j = 0; j < 256 - i; j++) { 272 for (int j = 0; j < 256 - i; j++) {
115 List<int> x = new List<int>(i); 273 List<int> x = new List<int>(i);
116 for (int k = 0; k < i; k++) { 274 for (int k = 0; k < i; k++) {
117 x[k] = j; 275 x[k] = j;
118 } 276 }
119 var enc = CryptoUtils.bytesToBase64(x); 277 var enc = BASE64.encode(x);
120 var dec = CryptoUtils.base64StringToBytes(enc); 278 var dec = BASE64.decode(enc);
121 expect(dec, orderedEquals(x)); 279 expect(dec, orderedEquals(x));
122 } 280 }
123 } 281 }
124 } 282 }
125 283
126 void _fillRandom(List<int> l) { 284 void _fillRandom(List<int> l) {
127 var random = new Random(0xBABE); 285 var random = new Random(0xBABE);
128 for (int j = 0; j < l.length; j++) { 286 for (int j = 0; j < l.length; j++) {
129 l[j] = random.nextInt(255); 287 l[j] = random.nextInt(255);
130 } 288 }
131 } 289 }
132 290
291 void _testOldApi() {
292 for (int i = 0; i < _INPUTS.length; i++) {
293 expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]);
294 expect(CryptoUtils.base64StringToBytes(_RESULTS[i]), _INPUTS[i].codeUnits);
295 }
296 }
297
133 void _testPerformance() { 298 void _testPerformance() {
134 var l = new List<int>(1024); 299 var l = new List<int>(1024);
135 var iters = 5000; 300 var iters = 5000;
136 _fillRandom(l); 301 _fillRandom(l);
137 String enc; 302 String enc;
138 var w = new Stopwatch()..start(); 303 var w = new Stopwatch()..start();
139 for( int i = 0; i < iters; ++i ) { 304 for( int i = 0; i < iters; ++i ) {
140 enc = CryptoUtils.bytesToBase64(l); 305 enc = BASE64.encode(l);
141 } 306 }
142 int ms = w.elapsedMilliseconds; 307 int ms = w.elapsedMilliseconds;
143 int perSec = (iters * l.length) * 1000 ~/ ms; 308 int perSec = (iters * l.length) * 1000 ~/ ms;
144 // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s"); 309 // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s");
145 w..reset(); 310 w..reset();
146 for( int i = 0; i < iters; ++i ) { 311 for( int i = 0; i < iters; ++i ) {
147 CryptoUtils.base64StringToBytes(enc); 312 BASE64.decode(enc);
148 } 313 }
149 ms = w.elapsedMilliseconds; 314 ms = w.elapsedMilliseconds;
150 perSec = (iters * l.length) * 1000 ~/ ms; 315 perSec = (iters * l.length) * 1000 ~/ ms;
151 // print('''Decode into ${l.length} bytes for $iters 316 // ('''Decode into ${l.length} bytes for $iters
152 // times: $ms msec. $perSec b/s'''); 317 // times: $ms msec. $perSec b/s''');
153 } 318 }
OLDNEW
« lib/src/base64.dart ('K') | « lib/src/crypto_utils.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698