| 1 | import encoding.base64 |
| 2 | |
| 3 | struct TestPair { |
| 4 | decoded string |
| 5 | encoded string |
| 6 | } |
| 7 | |
| 8 | const pairs = [ |
| 9 | // RFC 3548 examples |
| 10 | TestPair{'\x14\xfb\x9c\x03\xd9\x7e', 'FPucA9l+'}, |
| 11 | TestPair{'\x14\xfb\x9c\x03\xd9', 'FPucA9k='}, |
| 12 | TestPair{'\x14\xfb\x9c\x03', 'FPucAw=='}, |
| 13 | // RFC 4648 examples |
| 14 | TestPair{'', ''}, |
| 15 | TestPair{'f', 'Zg=='}, |
| 16 | TestPair{'fo', 'Zm8='}, |
| 17 | TestPair{'foo', 'Zm9v'}, |
| 18 | TestPair{'foob', 'Zm9vYg=='}, |
| 19 | TestPair{'fooba', 'Zm9vYmE='}, |
| 20 | TestPair{'foobar', 'Zm9vYmFy'}, |
| 21 | // Wikipedia examples |
| 22 | TestPair{'sure.', 'c3VyZS4='}, |
| 23 | TestPair{'sure', 'c3VyZQ=='}, |
| 24 | TestPair{'sur', 'c3Vy'}, |
| 25 | TestPair{'su', 'c3U='}, |
| 26 | TestPair{'leasure.', 'bGVhc3VyZS4='}, |
| 27 | TestPair{'easure.', 'ZWFzdXJlLg=='}, |
| 28 | TestPair{'asure.', 'YXN1cmUu'}, |
| 29 | TestPair{'sure.', 'c3VyZS4='}, |
| 30 | ] |
| 31 | |
| 32 | const man_pair = TestPair{'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.', 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='} |
| 33 | |
| 34 | fn test_decode() { |
| 35 | assert base64.decode(man_pair.encoded) == man_pair.decoded.bytes() |
| 36 | |
| 37 | // Test for incorrect padding. |
| 38 | assert base64.decode('aGk') == ''.bytes() |
| 39 | assert base64.decode('aGk=') == 'hi'.bytes() |
| 40 | assert base64.decode('aGk==') == ''.bytes() |
| 41 | |
| 42 | for i, p in pairs { |
| 43 | got := base64.decode(p.encoded) |
| 44 | if got != p.decoded.bytes() { |
| 45 | eprintln('pairs[${i}]: expected = ${p.decoded}, got = ${got}') |
| 46 | assert false |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | fn test_decode_str() { |
| 52 | assert base64.decode_str(man_pair.encoded) == man_pair.decoded |
| 53 | |
| 54 | // Test for incorrect padding. |
| 55 | assert base64.decode_str('aGk') == '' |
| 56 | assert base64.decode_str('aGk=') == 'hi' |
| 57 | assert base64.decode_str('aGk==') == '' |
| 58 | |
| 59 | for i, p in pairs { |
| 60 | got := base64.decode_str(p.encoded) |
| 61 | if got != p.decoded { |
| 62 | eprintln('pairs[${i}]: expected = ${p.decoded}, got = ${got}') |
| 63 | assert false |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | fn test_encode() { |
| 69 | assert base64.encode(man_pair.decoded.bytes()) == man_pair.encoded |
| 70 | |
| 71 | for i, p in pairs { |
| 72 | got := base64.encode(p.decoded.bytes()) |
| 73 | if got != p.encoded { |
| 74 | eprintln('pairs[${i}]: expected = ${p.encoded}, got = ${got}') |
| 75 | assert false |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | fn test_encode_str() { |
| 81 | assert base64.encode_str(man_pair.decoded) == man_pair.encoded |
| 82 | |
| 83 | for i, p in pairs { |
| 84 | got := base64.encode_str(p.decoded) |
| 85 | if got != p.encoded { |
| 86 | eprintln('pairs[${i}]: expected = ${p.encoded}, got = ${got}') |
| 87 | assert false |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | fn test_url_encode() { |
| 93 | test := base64.url_encode('Hello Base64Url encoding!'.bytes()) |
| 94 | assert test == 'SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ' |
| 95 | } |
| 96 | |
| 97 | fn test_url_encode_str() { |
| 98 | test := base64.url_encode_str('Hello Base64Url encoding!') |
| 99 | assert test == 'SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ' |
| 100 | } |
| 101 | |
| 102 | fn test_url_decode() { |
| 103 | test := base64.url_decode('SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ') |
| 104 | assert test == 'Hello Base64Url encoding!'.bytes() |
| 105 | } |
| 106 | |
| 107 | fn test_url_decode_str() { |
| 108 | test := base64.url_decode_str('SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ') |
| 109 | assert test == 'Hello Base64Url encoding!' |
| 110 | } |
| 111 | |
| 112 | fn test_encode_null_u8() { |
| 113 | assert base64.encode([u8(`A`), 0, `C`]) == 'QQBD' |
| 114 | } |
| 115 | |
| 116 | fn test_encode_null_byte_str() { |
| 117 | // While this works, bytestr() does a memcpy |
| 118 | s := [u8(`A`), 0, `C`].bytestr() |
| 119 | assert base64.encode_str(s) == 'QQBD' |
| 120 | } |
| 121 | |
| 122 | fn test_decode_null_u8() { |
| 123 | assert base64.decode('QQBD') == [u8(`A`), 0, `C`] |
| 124 | } |
| 125 | |
| 126 | fn test_decode_null_byte_str() { |
| 127 | // While this works, bytestr() does a memcpy |
| 128 | s := [u8(`A`), 0, `C`].bytestr() |
| 129 | assert base64.decode_str('QQBD') == s |
| 130 | } |
| 131 | |
| 132 | fn test_decode_in_buffer_bytes() { |
| 133 | rfc4648_pairs := [ |
| 134 | TestPair{'foob', 'Zm9vYg=='}, |
| 135 | TestPair{'fooba', 'Zm9vYmE='}, |
| 136 | TestPair{'foobar', 'Zm9vYmFy'}, |
| 137 | ] |
| 138 | mut src_dec_buf := []u8{len: 8} |
| 139 | mut src_enc_buf := []u8{len: 8} |
| 140 | mut out_buf := []u8{len: 8} |
| 141 | |
| 142 | for p in rfc4648_pairs { |
| 143 | src_dec_buf = p.decoded.bytes() |
| 144 | src_enc_buf = p.encoded.bytes() |
| 145 | n := base64.decode_in_buffer_bytes(src_enc_buf, out_buf.data) |
| 146 | assert src_dec_buf == out_buf[..n] |
| 147 | } |
| 148 | } |
| 149 | |