| OLD | NEW |
| 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 "package:expect/expect.dart"; | |
| 9 import "package:crypto/crypto.dart"; | |
| 10 import 'dart:math'; | 8 import 'dart:math'; |
| 11 | 9 |
| 10 import "package:crypto/crypto.dart"; |
| 11 import "package:unittest/unittest.dart"; |
| 12 |
| 13 void main() { |
| 14 test('encoder', _testEncoder); |
| 15 test('decoder', _testDecoder); |
| 16 test('decoder for malformed input', _testDecoderForMalformedInput); |
| 17 test('encode decode lists', _testEncodeDecodeLists); |
| 18 test('url safe encode-decode', _testUrlSafeEncodeDecode); |
| 19 test('performance', _testPerformance); |
| 20 } |
| 21 |
| 12 // Data from http://tools.ietf.org/html/rfc4648. | 22 // Data from http://tools.ietf.org/html/rfc4648. |
| 13 var inputs = | 23 const _INPUTS = |
| 14 const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar']; | 24 const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar']; |
| 15 var results = | 25 const _RESULTS = |
| 16 const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy']; | 26 const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy']; |
| 17 | 27 |
| 18 // Test data with only zeroes. | 28 // Test data with only zeroes. |
| 19 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []]; | 29 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []]; |
| 20 var resultsWithZeroes = ['AAAA', 'AAA=', 'AA==', '']; | 30 const _RESULTS_WITH_ZEROS = const ['AAAA', 'AAA=', 'AA==', '']; |
| 21 | 31 |
| 22 var longLine = | 32 const _LONG_LINE = |
| 23 "Man is distinguished, not only by his reason, but by this singular " | 33 "Man is distinguished, not only by his reason, but by this singular " |
| 24 "passion from other animals, which is a lust of the mind, that by a " | 34 "passion from other animals, which is a lust of the mind, that by a " |
| 25 "perseverance of delight in the continued and indefatigable generation " | 35 "perseverance of delight in the continued and indefatigable generation " |
| 26 "of knowledge, exceeds the short vehemence of any carnal pleasure."; | 36 "of knowledge, exceeds the short vehemence of any carnal pleasure."; |
| 27 | 37 |
| 28 var longLineResult = | 38 const _LONG_LINE_RESULT = |
| 29 "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbm" | 39 "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbm" |
| 30 "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\r\n" | 40 "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\r\n" |
| 31 "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci" | 41 "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci" |
| 32 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg\r\n" | 42 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg\r\n" |
| 33 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" | 43 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" |
| 34 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu\r\n" | 44 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu\r\n" |
| 35 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" | 45 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" |
| 36 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo\r\n" | 46 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo\r\n" |
| 37 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" | 47 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" |
| 38 "5hbCBwbGVhc3VyZS4="; | 48 "5hbCBwbGVhc3VyZS4="; |
| 39 | 49 |
| 40 var longLineResultNoBreak = | 50 const _LONG_LINE_RESULT_NO_BREAK = |
| 41 "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbm" | 51 "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbm" |
| 42 "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" | 52 "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" |
| 43 "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci" | 53 "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci" |
| 44 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" | 54 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" |
| 45 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" | 55 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" |
| 46 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" | 56 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" |
| 47 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" | 57 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" |
| 48 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" | 58 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" |
| 49 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" | 59 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" |
| 50 "5hbCBwbGVhc3VyZS4="; | 60 "5hbCBwbGVhc3VyZS4="; |
| 51 | 61 |
| 52 testEncoder() { | 62 void _testEncoder() { |
| 53 for (var i = 0; i < inputs.length; i++) { | 63 for (var i = 0; i < _INPUTS.length; i++) { |
| 54 Expect.equals(results[i], CryptoUtils.bytesToBase64(inputs[i].codeUnits)); | 64 expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]); |
| 55 } | 65 } |
| 56 for (var i = 0; i < inputsWithZeroes.length; i++) { | 66 for (var i = 0; i < inputsWithZeroes.length; i++) { |
| 57 Expect.equals(resultsWithZeroes[i], | 67 expect(CryptoUtils.bytesToBase64(inputsWithZeroes[i]), |
| 58 CryptoUtils.bytesToBase64(inputsWithZeroes[i])); | 68 _RESULTS_WITH_ZEROS[i]); |
| 59 } | 69 } |
| 60 Expect.equals( | 70 expect( |
| 61 CryptoUtils.bytesToBase64(longLine.codeUnits, addLineSeparator : true), | 71 CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits, addLineSeparator : true), |
| 62 longLineResult); | 72 _LONG_LINE_RESULT); |
| 63 Expect.equals(CryptoUtils.bytesToBase64(longLine.codeUnits), | 73 expect(CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits), |
| 64 longLineResultNoBreak); | 74 _LONG_LINE_RESULT_NO_BREAK); |
| 65 } | 75 } |
| 66 | 76 |
| 67 testDecoder() { | 77 void _testDecoder() { |
| 68 for (var i = 0; i < results.length; i++) { | 78 for (var i = 0; i < _RESULTS.length; i++) { |
| 69 Expect.equals(inputs[i], | 79 expect( |
| 70 new String.fromCharCodes(CryptoUtils.base64StringToBytes(results[i]))); | 80 new String.fromCharCodes(CryptoUtils.base64StringToBytes(_RESULTS[i])), |
| 81 _INPUTS[i]); |
| 71 } | 82 } |
| 72 for (var i = 0; i < resultsWithZeroes.length; i++) { | 83 for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) { |
| 73 Expect.listEquals(inputsWithZeroes[i], | 84 expect(CryptoUtils.base64StringToBytes(_RESULTS_WITH_ZEROS[i]), |
| 74 CryptoUtils.base64StringToBytes(resultsWithZeroes[i])); | 85 inputsWithZeroes[i]); |
| 75 } | 86 } |
| 76 var longLineDecoded = CryptoUtils.base64StringToBytes(longLineResult); | 87 var longLineDecoded = CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT); |
| 77 Expect.equals(new String.fromCharCodes(longLineDecoded), longLine); | 88 expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE); |
| 78 var longLineResultNoBreak = CryptoUtils.base64StringToBytes(longLineResult); | 89 var longLineResultNoBreak = |
| 79 Expect.equals(new String.fromCharCodes(longLineResultNoBreak), longLine); | 90 CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT); |
| 91 expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE); |
| 80 } | 92 } |
| 81 | 93 |
| 82 testDecoderForMalformedInput() { | 94 void _testDecoderForMalformedInput() { |
| 83 Expect.throws(() { | 95 expect(() { |
| 84 CryptoUtils.base64StringToBytes('AB~'); | 96 CryptoUtils.base64StringToBytes('AB~'); |
| 85 }, (e) => e is FormatException); | 97 }, throwsFormatException); |
| 86 | 98 |
| 87 Expect.throws(() { | 99 expect(() { |
| 88 CryptoUtils.base64StringToBytes('A'); | 100 CryptoUtils.base64StringToBytes('A'); |
| 89 }, (e) => e is FormatException); | 101 }, throwsFormatException); |
| 90 } | 102 } |
| 91 | 103 |
| 92 testUrlSafeEncodeDecode() { | 104 void _testUrlSafeEncodeDecode() { |
| 93 List<int> decUrlSafe = CryptoUtils.base64StringToBytes('-_A='); | 105 List<int> decUrlSafe = CryptoUtils.base64StringToBytes('-_A='); |
| 94 List<int> dec = CryptoUtils.base64StringToBytes('+/A='); | 106 List<int> dec = CryptoUtils.base64StringToBytes('+/A='); |
| 95 Expect.listEquals(decUrlSafe, dec); | 107 expect(decUrlSafe, dec); |
| 96 Expect.equals('-_A=', CryptoUtils.bytesToBase64(dec, urlSafe: true)); | 108 expect(CryptoUtils.bytesToBase64(dec, urlSafe: true), '-_A='); |
| 97 Expect.equals('+/A=', CryptoUtils.bytesToBase64(dec)); | 109 expect(CryptoUtils.bytesToBase64(dec), '+/A='); |
| 98 } | 110 } |
| 99 | 111 |
| 100 testEncodeDecodeLists() { | 112 void _testEncodeDecodeLists() { |
| 101 for (int i = 0; i < 10; i++) { | 113 for (int i = 0; i < 10; i++) { |
| 102 for (int j = 0; j < 256 - i; j++) { | 114 for (int j = 0; j < 256 - i; j++) { |
| 103 List<int> x = new List<int>(i); | 115 List<int> x = new List<int>(i); |
| 104 for (int k = 0; k < i; k++) { | 116 for (int k = 0; k < i; k++) { |
| 105 x[k] = j; | 117 x[k] = j; |
| 106 } | 118 } |
| 107 var enc = CryptoUtils.bytesToBase64(x); | 119 var enc = CryptoUtils.bytesToBase64(x); |
| 108 var dec = CryptoUtils.base64StringToBytes(enc); | 120 var dec = CryptoUtils.base64StringToBytes(enc); |
| 109 Expect.listEquals(x, dec); | 121 expect(dec, x); |
| 110 } | 122 } |
| 111 } | 123 } |
| 112 } | 124 } |
| 113 | 125 |
| 114 fillRandom(List<int> l) { | 126 void _fillRandom(List<int> l) { |
| 115 var random = new Random(0xBABE); | 127 var random = new Random(0xBABE); |
| 116 for(int j=0; j < l.length; j++) { | 128 for (int j = 0; j < l.length; j++) { |
| 117 l[j] = random.nextInt(255); | 129 l[j] = random.nextInt(255); |
| 118 } | 130 } |
| 119 } | 131 } |
| 120 | 132 |
| 121 testPerformance() { | 133 void _testPerformance() { |
| 122 var l = new List<int>(1024); | 134 var l = new List<int>(1024); |
| 123 var iters = 5000; | 135 var iters = 5000; |
| 124 fillRandom(l); | 136 _fillRandom(l); |
| 125 String enc; | 137 String enc; |
| 126 var w = new Stopwatch()..start(); | 138 var w = new Stopwatch()..start(); |
| 127 for( int i = 0; i < iters; ++i ) { | 139 for( int i = 0; i < iters; ++i ) { |
| 128 enc = CryptoUtils.bytesToBase64(l); | 140 enc = CryptoUtils.bytesToBase64(l); |
| 129 } | 141 } |
| 130 int ms = w.elapsedMilliseconds; | 142 int ms = w.elapsedMilliseconds; |
| 131 int perSec = (iters * l.length) * 1000 ~/ ms; | 143 int perSec = (iters * l.length) * 1000 ~/ ms; |
| 132 // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s"); | 144 // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s"); |
| 133 w..reset(); | 145 w..reset(); |
| 134 for( int i = 0; i < iters; ++i ) { | 146 for( int i = 0; i < iters; ++i ) { |
| 135 CryptoUtils.base64StringToBytes(enc); | 147 CryptoUtils.base64StringToBytes(enc); |
| 136 } | 148 } |
| 137 ms = w.elapsedMilliseconds; | 149 ms = w.elapsedMilliseconds; |
| 138 perSec = (iters * l.length) * 1000 ~/ ms; | 150 perSec = (iters * l.length) * 1000 ~/ ms; |
| 139 // print('''Decode into ${l.length} bytes for $iters | 151 // print('''Decode into ${l.length} bytes for $iters |
| 140 // times: $ms msec. $perSec b/s'''); | 152 // times: $ms msec. $perSec b/s'''); |
| 141 } | 153 } |
| 142 | |
| 143 void main() { | |
| 144 testEncoder(); | |
| 145 testDecoder(); | |
| 146 testDecoderForMalformedInput(); | |
| 147 testEncodeDecodeLists(); | |
| 148 testUrlSafeEncodeDecode(); | |
| 149 testPerformance(); | |
| 150 } | |
| OLD | NEW |